Skip to content

Commit

Permalink
ncm-metaconfig/ssh: Implement SSH daemon configuration
Browse files Browse the repository at this point in the history
The main driver was getting support for "Match ..." blocks, which would
have been more dificult to add to ncm-ssh.
  • Loading branch information
gombasg committed Apr 11, 2019
1 parent dcd4cdc commit b792116
Show file tree
Hide file tree
Showing 8 changed files with 389 additions and 0 deletions.
109 changes: 109 additions & 0 deletions ncm-metaconfig/src/main/metaconfig/ssh/pan/schema.pan
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,112 @@ type ssh_config_file = {
'main' ? ssh_config_opts
};

# Not all options may appear inside a Match block
type sshd_config_match_opts = {
'AcceptEnv' ? string[]
'AllowAgentForwarding' ? boolean
'AllowGroups' ? string[]
'AllowStreamLocalForwarding' ? string with match (SELF, "^(yes|all|no|local|remote)$")
'AllowTcpForwarding' ? string with match (SELF, "^(yes|all|no|local|remote)$")
'AllowUsers' ? string[]
'AuthenticationMethods' ? string[] # Don't go into details - it does not seem to worth the effort
'AuthorizedKeysCommand' ? absolute_file_path
'AuthorizedKeysCommandUser' ? string
'AuthorizedKeysFile' ? string[]
'AuthorizedPrincipalsCommand' ? absolute_file_path
'AuthorizedPrincipalsCommandUser' ? string
'AuthorizedPrincipalsFile' ? string[]
'Banner' ? string
'ChrootDirectory' ? string
'ClientAliveCountMax' ? long(1..)
'ClientAliveInterval' ? long(0..)
'DenyGroups' ? string[]
'DenyUsers' ? string[]
'ForceCommand' ? string
'GatewayPorts' ? string with match (SELF, "^(yes|no|clientspecified)$")
'GSSAPIAuthentication' ? boolean
'HostbasedAcceptedKeyTypes' ? temp_ssh_hostkeyalgorithms[]
'HostbasedAuthentication' ? boolean
'HostbasedUsesNameFromPacketOnly' ? boolean
'IPQoS' ? string[] with length(SELF) == 1 || length(SELF) == 2
'KbdInteractiveAuthentication' ? boolean
'KerberosAuthentication' ? boolean
'LogLevel' ? string with match (SELF, "^(QUIET|FATAL|ERROR|INFO|VERBOSE|DEBUG[123]?)$")
'MaxAuthTries' ? long(1..)
'MaxSessions' ? long(0..)
'PasswordAuthentication' ? boolean
'PermitEmptyPasswords' ? boolean
'PermitListen' ? string[] # type_hostport would not allow wildcards
'PermitOpen' ? string[] # type_hostport would not allow wildcards
'PermitRootLogin' ? string with match (SELF, "^(yes|prohibit-password|without-password|forced-commands-only|no)$")
'PermitTTY' ? boolean
'PermitTunnel' ? string with match (SELF, "^(yes|point-to-point|ethernet|no)$")
'PermitUserRC' ? boolean
'PubkeyAcceptedKeyTypes' ? temp_ssh_hostkeyalgorithms[]
'PubkeyAuthentication' ? boolean
'RekeyLimit' ? string[] with length(SELF) == 1 || length(SELF) == 2
'RSAAuthentication' ? boolean
'RhostsRSAAuthentication' ? boolean
'RevokedKeys' ? string
'RDomain' ? string
'SetEnv' ? string{}
'StreamLocalBindMask' ? string with match (SELF, "^[0-7]{3,5}$")
'StreamLocalBindUnlink' ? boolean
'TrustedUserCAKeys' ? string
'X11DisplayOffset' ? long(0..)
'X11Forwarding' ? boolean
'X11UseLocalHost' ? boolean
};

type sshd_config_match = {
"matches" : string[]
include sshd_config_match_opts
};

type sshd_config_opts = {
include sshd_config_match_opts
'AddressFamily' ? string with match (SELF, "^(any|inet|inet6)$")
'ChallengeResponseAuthentication' ? boolean
'Ciphers' ? temp_ssh_ciphers[]
'Compression' ? boolean
'DisableForwarding' ? boolean
'ExposeAuthInfo' ? boolean
'FingerprintHash' ? string with match (SELF, "^(md5|sha256)$")
'GSSAPICleanupCredentials' ? boolean
'GSSAPIKeyExchange' ? boolean
'GSSAPIStrictAcceptorCheck' ? boolean
'GSSAPIStoreCredentialsOnRekey' ? boolean
'HostCertificate' ? string
'HostKey' ? string[]
'HostKeyAgent' ? string
'HostKeyAlgorithms' ? temp_ssh_hostkeyalgorithms[]
'IgnoreRhosts' ? boolean
'IgnoreUserKnownHosts' ? boolean
'KerberosGetAFSToken' ? boolean
'KerberosOrLocalPasswd' ? boolean
'KerberosTicketCleanup' ? boolean
'KexAlgorithms' ? temp_ssh_kexalgorithms[]
'ListenAddress' ? type_hostport[]
'LoginGraceTime' ? long(0..)
'MACs' ? temp_ssh_MACs[]
'Match' ? sshd_config_match[]
'MaxStartups' ? string with match (SELF, "^[0-9]+(:[0-9]+:[0-9]+)?$")
'PermitUserEnvironment' ? boolean
'PidFile' ? absolute_file_path
'Port' ? long(1..)[]
'PrintLastLog' ? boolean
'PrintMotd' ? boolean
'StrictModes' ? boolean
'Subsystem' ? string{}
'SyslogFacility' ? string with match (SELF, "^(DAEMON|USER|AUTH|LOCAL[0-7])$")
'TCPKeepAlive' ? boolean
'UseDNS' ? boolean
'UsePAM' ? boolean
'VersionAddendum' ? string
'XAuthLocation' ? absolute_file_path
};

type sshd_config_file = {
'Match' ? sshd_config_match[]
'main' ? sshd_config_opts
};
8 changes: 8 additions & 0 deletions ncm-metaconfig/src/main/metaconfig/ssh/pan/server_config.pan
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
unique template metaconfig/ssh/server_config;

include 'metaconfig/ssh/schema';

bind "/software/components/metaconfig/services/{/etc/ssh/sshd_config}/contents" = sshd_config_file;

prefix "/software/components/metaconfig/services/{/etc/ssh/sshd_config}";
"module" = "ssh/server";
7 changes: 7 additions & 0 deletions ncm-metaconfig/src/main/metaconfig/ssh/server.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

[% INCLUDE metaconfig/ssh/server_attrs.tt data=main -%]

[% FOREACH mt IN Match -%]
Match [% mt.matches.join(' ') %]
[% INCLUDE metaconfig/ssh/server_attrs.tt data=mt FILTER indent %]
[% END -%]
44 changes: 44 additions & 0 deletions ncm-metaconfig/src/main/metaconfig/ssh/server_attrs.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[% spacelist = ['AcceptEnv', 'AllowGroups', 'AllowUsers', 'AuthenticationMethods', 'AuthorizedKeysFile', 'AuthorizedPrincipalsFile',
'DenyGroups', 'DenyUsers',
'IPQoS',
'PermitListen', 'PermitOpen',
'RekeyLimit' ] -%]
[% commalist = ['Ciphers', 'HostKeyAlgorithms', 'HostbasedAcceptedKeyTypes', 'KexAlgorithms', 'MACs', 'PubkeyAcceptedKeyTypes' ] -%]
[% multilinelist = ['HostKey', 'ListenAddress', 'Port' ] -%]
[% booleans = ['AllowAgentForwarding',
'ChallengeResponseAuthentication', 'Compression',
'ExposeAuthInfo',
'GSSAPIAuthentication', 'GSSAPICleanupCredentials', 'GSSAPIKeyExchange', 'GSSAPIStrictAcceptorCheck', 'GSSAPIStoreCredentialsOnRekey',
'HostbasedAuthentication', 'HostbasedUsesNameFromPacketOnly',
'IgnoreRhosts', 'IgnoreUserKnownHosts',
'KbdInteractiveAuthentication', 'KerberosAuthentication', 'KerberosGetAFSToken', 'KerberosOrLocalPasswd', 'KerberosTicketCleanup',
'PasswordAuthentication', 'PermitEmptyPasswords', 'PermitRootLogin', 'PermitTTY', 'PermitTunnel', 'PermitUserEnvironment',
'PermitUserRC', 'PrintLastLog', 'PrintMotd', 'PubkeyAuthentication',
'StreamLocalBindUnlink', 'StrictModes',
'TCPKeepAlive', 'UseDNS', 'UsePAM', 'X11Forwarding', 'X11UseLocalhost'] -%]

[%- FOREACH pair IN data.pairs -%]
[% NEXT IF pair.key == 'matches' -%]
[% SWITCH pair.key -%]
[% CASE booleans -%]
[% pair.key %] [% pair.value ? 'Yes' : 'No' %]
[% CASE spacelist -%]
[% pair.key %] [% pair.value.join(' ') %]
[% CASE commalist -%]
[% pair.key %] [% pair.value.join(',') %]
[% CASE multilinelist -%]
[% FOREACH line IN pair.value -%]
[% pair.key %] [% line %]
[% END -%]
[% CASE 'Subsystem' -%]
[% FOREACH item IN pair.value.pairs -%]
Subsystem [% item.key %] [% item.value %]
[% END -%]
[% CASE 'SetEnv' -%]
[% FOREACH item IN pair.value.pairs -%]
SetEnv [% item.key %]="[% item.value %]"
[% END -%]
[% CASE -%]
[% pair.key %] [% pair.value %]
[% END -%]
[% END -%]
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
object template server_allopts;

include 'metaconfig/ssh/server_config';

prefix "/software/components/metaconfig/services/{/etc/ssh/sshd_config}/contents";

"main/AcceptEnv" = list("LC_CTYPE", "LANG", "TERM");
"main/AddressFamily" = "any";
"main/AllowAgentForwarding" = false;
"main/AllowGroups" = list("wheel");
"main/AllowStreamLocalForwarding" = "local";
"main/AllowTcpForwarding" = "local";
"main/AllowUsers" = list("quattor");
"main/AuthenticationMethods" = list("any");
"main/AuthorizedKeysCommand" = "/usr/sbin/key-lookup";
"main/AuthorizedKeysCommandUser" = "keyuser";
"main/AuthorizedKeysFile" = list("/etc/ssh/authorized_keys", ".ssh/authorized_keys");
"main/AuthorizedPrincipalsCommand" = "/usr/sbin/principal-lookup";
"main/AuthorizedPrincipalsCommandUser" = "princuser";
"main/AuthorizedPrincipalsFile" = list("/etc/ssh/x509_users", ".ssh/x509_users");
"main/Banner" = "Configured by Quattor";
"main/ChallengeResponseAuthentication" = false;
"main/ChrootDirectory" = "/srv/ssh";
"main/Ciphers" = list("chacha20-poly1305@openssh.com", "arcfour256", "arcfour128", "aes128-cbc", "3des-cbc");
"main/ClientAliveCountMax" = 3;
"main/ClientAliveInterval" = 30;
"main/Compression" = false;
"main/DenyGroups" = list("adm");
"main/DenyUsers" = list("root");
"main/DisableForwarding" = false;
"main/ExposeAuthInfo" = false;
"main/FingerprintHash" = "sha256";
"main/ForceCommand" = "cat /etc/motd";
"main/GatewayPorts" = "clientspecified";
"main/GSSAPIAuthentication" = true;
"main/GSSAPICleanupCredentials" = true;
"main/GSSAPIKeyExchange" = true;
"main/GSSAPIStrictAcceptorCheck" = true;
"main/GSSAPIStoreCredentialsOnRekey" = true;
"main/HostbasedAcceptedKeyTypes" = list("-ssh-rsa");
"main/HostbasedAuthentication" = true;
"main/HostbasedUsesNameFromPacketOnly" = false;
"main/HostCertificate" = "/etc/ssh/ssh_host_cert.pem";
"main/HostKey" = list("/etc/ssh/ssh_host_rsa_key", "/etc/ssh/ssh_host_ed25519_key");
"main/HostKeyAgent" = "/run/ssh/key_agent.socket";
"main/HostKeyAlgorithms" = list("ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521");
"main/IPQoS" = list("lowdelay", "throughput");
"main/IgnoreRhosts" = true;
"main/IgnoreUserKnownHosts" = true;
"main/KbdInteractiveAuthentication" = true;
"main/KerberosAuthentication" = false;
"main/KerberosGetAFSToken" = false;
"main/KerberosOrLocalPasswd" = false;
"main/KerberosTicketCleanup" = true;
"main/KexAlgorithms" = list("ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521");
"main/ListenAddress" = list("127.0.0.1:22", "192.168.0.1:22", "192.168.0.1:2200");
"main/LogLevel" = "DEBUG3";
"main/LoginGraceTime" = 60;
"main/MACs" = list("hmac-sha1-96-etm@openssh.com", "hmac-md5-96-etm@openssh.com");
"main/MaxAuthTries" = 3;
"main/MaxSessions" = 10;
"main/MaxStartups" = "10:30:100";
"main/PasswordAuthentication" = false;
"main/PermitEmptyPasswords" = false;
"main/PermitListen" = list("8080", "127.0.0.1:*");
"main/PermitOpen" = list("8080", "192.168.0.1:*");
"main/PermitRootLogin" = "prohibit-password";
"main/PermitTTY" = true;
"main/PermitTunnel" = "point-to-point";
"main/PermitUserEnvironment" = false;
"main/PermitUserRC" = false;
"main/PidFile" = "/run/sshd.pid";
"main/Port" = list(22, 2200);
"main/PrintLastLog" = true;
"main/PrintMotd" = true;
"main/PubkeyAcceptedKeyTypes" = list("-ssh-rsa");
"main/PubkeyAuthentication" = true;
"main/RDomain" = "%D";
"main/RSAAuthentication" = false;
"main/RekeyLimit" = list("1G", "300s");
"main/RevokedKeys" = "/etc/ssh/revoked_keys";
"main/RhostsRSAAuthentication" = false;
"main/SetEnv" = dict("LC_ALL", "C", "TERM", "xterm");
"main/StreamLocalBindMask" = "0177";
"main/StreamLocalBindUnlink" = false;
"main/Subsystem" = dict("sftp", "internal-sftp");
"main/SyslogFacility" = "AUTH";
"main/TCPKeepAlive" = true;
"main/TrustedUserCAKeys" = "/etc/ssh/trusted_cas";
"main/UseDNS" = true;
"main/UsePAM" = true;
"main/VersionAddendum" = "extra";
"main/X11DisplayOffset" = 10;
"main/X11Forwarding" = true;
"main/X11UseLocalHost" = true;
"main/XAuthLocation" = "/usr/bin/xauth";
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
object template server_config;

include 'metaconfig/ssh/server_config';

prefix "/software/components/metaconfig/services/{/etc/ssh/sshd_config}/contents";

"main/AddressFamily" = "any";
"main/Ciphers" = list("aes128-ctr", "aes192-ctr", "aes256-ctr");
"main/PasswordAuthentication" = false;
"main/Subsystem" = dict("sftp", "internal-sftp");

'Match' = append(
dict(
"matches", list("User testuser2", "Address 192.168.0.0/16"),
"PasswordAuthentication", true,
)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
Base test for all ssh server config options
---
/etc/ssh/sshd_config
---
^AcceptEnv\sLC_CTYPE\sLANG\sTERM$
^AddressFamily\sany$
^AllowAgentForwarding\sNo$
^AllowGroups\swheel$
^AllowStreamLocalForwarding\slocal$
^AllowTcpForwarding\slocal$
^AllowUsers\squattor$
^AuthenticationMethods\sany$
^AuthorizedKeysCommand\s/usr/sbin/key-lookup$
^AuthorizedKeysCommandUser\skeyuser$
^AuthorizedKeysFile\s/etc/ssh/authorized_keys\s\.ssh/authorized_keys$
^AuthorizedPrincipalsCommand\s/usr/sbin/principal-lookup$
^AuthorizedPrincipalsCommandUser\sprincuser$
^AuthorizedPrincipalsFile\s/etc/ssh/x509_users\s\.ssh/x509_users$
^Banner\sConfigured by Quattor$
^ChallengeResponseAuthentication\sNo$
^ChrootDirectory\s/srv/ssh$
^Ciphers\schacha20-poly1305@openssh.com,arcfour256,arcfour128,aes128-cbc,3des-cbc$
^ClientAliveCountMax\s3$
^ClientAliveInterval\s30$
^Compression\sNo$
^DenyGroups\sadm$
^DenyUsers\sroot$
^DisableForwarding\s0$
^ExposeAuthInfo\sNo$
^FingerprintHash\ssha256$
^ForceCommand\scat\s/etc/motd$
^GSSAPIAuthentication\sYes$
^GSSAPICleanupCredentials\sYes$
^GSSAPIKeyExchange\sYes$
^GSSAPIStoreCredentialsOnRekey\sYes$
^GSSAPIStrictAcceptorCheck\sYes$
^GatewayPorts\sclientspecified$
^HostCertificate\s/etc/ssh/ssh_host_cert.pem$
^HostKey\s/etc/ssh/ssh_host_rsa_key$
^HostKey\s/etc/ssh/ssh_host_ed25519_key$
^HostKeyAgent\s/run/ssh/key_agent\.socket$
^HostKeyAlgorithms\secdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521$
^HostbasedAcceptedKeyTypes\s-ssh-rsa$
^HostbasedAuthentication\sYes$
^HostbasedUsesNameFromPacketOnly\sNo$
^IPQoS\slowdelay\sthroughput$
^IgnoreRhosts\sYes$
^IgnoreUserKnownHosts\sYes$
^KbdInteractiveAuthentication\sYes$
^KerberosAuthentication\sNo$
^KerberosGetAFSToken\sNo$
^KerberosOrLocalPasswd\sNo$
^KerberosTicketCleanup\sYes$
^KexAlgorithms\secdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521$
^ListenAddress\s127\.0\.0\.1:22$
^ListenAddress\s192\.168\.0\.1:22$
^ListenAddress\s192\.168\.0\.1:2200$
^LogLevel\sDEBUG3$
^LoginGraceTime\s60$
^MACs\shmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com$
^MaxAuthTries\s3$
^MaxSessions\s10$
^MaxStartups\s10:30:100$
^PasswordAuthentication\sNo$
^PermitEmptyPasswords\sNo$
^PermitListen\s8080\s127\.0\.0\.1:\*$
^PermitOpen\s8080\s192\.168\.0\.1:\*$
^PermitRootLogin\sYes$
^PermitTTY\sYes$
^PermitTunnel\sYes$
^PermitUserEnvironment\sNo$
^PermitUserRC\sNo$
^PidFile\s/run/sshd\.pid$
^Port\s22$
^Port\s2200$
^PrintLastLog\sYes$
^PrintMotd\sYes$
^PubkeyAcceptedKeyTypes\s-ssh-rsa$
^PubkeyAuthentication\sYes$
^RDomain\s%D$
^RSAAuthentication\s0$
^RekeyLimit\s1G\s300s$
^RevokedKeys\s/etc/ssh/revoked_keys$
^RhostsRSAAuthentication\s0$
^SetEnv\sLC_ALL="C"$
^SetEnv\sTERM="xterm"$
^StreamLocalBindMask\s0177$
^StreamLocalBindUnlink\sNo$
^Subsystem\ssftp\sinternal-sftp$
^SyslogFacility\sAUTH$
^TCPKeepAlive\sYes$
^TrustedUserCAKeys\s/etc/ssh/trusted_cas$
^UseDNS\sYes$
^UsePAM\sYes$
^VersionAddendum\sextra$
^X11DisplayOffset\s10$
^X11Forwarding\sYes$
^X11UseLocalHost\s1$
^XAuthLocation\s/usr/bin/xauth$
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Base test for ssh server config
---
/etc/ssh/sshd_config
---
^AddressFamily\sany$
^Ciphers\saes128-ctr,aes192-ctr,aes256-ctr$
^PasswordAuthentication\sNo$
^Match\sUser\stestuser2\sAddress\s192.168.0.0/16$
^\s{4}PasswordAuthentication\sYes$

0 comments on commit b792116

Please sign in to comment.