-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1452 from stdweird/gombasg-ssh_metaconfig
ncm-metaconfig: ssh daemon configuration support
- Loading branch information
Showing
15 changed files
with
577 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,28 @@ | ||
[% spacelist = ['SendEnv', 'GlobalKnownHostsFile', 'IgnoreUnknown', 'UserKnownHostsFile' ] -%] | ||
[% commalist = ['Ciphers', 'HostbasedKeyTypes','HostKeyAlgorithms', 'KbdInteractiveDevices', 'KbdInteractiveDevices', | ||
'MACs', 'PreferredAuthentications', 'CanonicalDomains', 'CanonicalizePermittedCNAMEs', 'KexAlgorithms', | ||
] -%] | ||
[% multilinelist = ['IdentityFile', 'RevokedHostKeys'] -%] | ||
[% booleans = ['BatchMode', 'CanonicalizeFallbackLocal', 'ChallengeResponseAuthentication', 'CheckHostIP', | ||
'ClearAllForwardings', 'Compression', 'EnableSSHKeysign', 'ExitOnForwardFailure', 'ForwardAgent', 'ForwardX11', | ||
'ForwardX11Trusted', 'GatewayPorts', 'GSSAPIAuthentication', 'GSSAPIDelegateCredentials', 'HashKnownHosts', | ||
'HostbasedAuthentication', 'IdentitiesOnly', 'KbdInteractiveAuthentication', 'NoHostAuthenticationForLocalhost', | ||
'PasswordAuthentication', 'PermitLocalCommand', 'ProxyUseFdpass', 'PubkeyAuthentication', 'RhostsRSAAuthentication', | ||
'RSAAuthentication', 'StreamLocalBindUnlink', 'TCPKeepAlive', 'UsePrivilegedPort', 'VisualHostKey', | ||
] -%] | ||
|
||
[% # different forms of list handling, default for list type is comma separated | ||
spacelist = ['SendEnv', 'GlobalKnownHostsFile', 'IgnoreUnknown', 'Include', 'UserKnownHostsFile' ]; | ||
multilinelist = ['CertificateFile', 'IdentityFile', 'RevokedHostKeys']; | ||
-%] | ||
[%- FOREACH pair IN data.pairs -%] | ||
[% NEXT IF pair.key == 'hostnames' || pair.key == 'matches' -%] | ||
[% SWITCH pair.key -%] | ||
[% CASE booleans -%] | ||
[% pair.key %] [% pair.value ? 'Yes' : 'No' %] | ||
[% CASE ['hostnames', 'matches'] %][% # Do nothing -%] | ||
[% 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 'SetEnv' -%] | ||
[% FOREACH item IN pair.value.pairs -%] | ||
SetEnv [% item.key %]="[% item.value %]" | ||
[% END -%] | ||
[% CASE -%] | ||
[% pair.key %] [% pair.value %] | ||
[% END -%] | ||
[% pair.key %] [% -%] | ||
[% IF pair.value.is_boolean -%] | ||
[% pair.value ? 'yes' : 'no' -%] | ||
[% ELSIF CCM.is_list(pair.value) -%] | ||
[% pair.value.join(',') -%] | ||
[% ELSE -%] | ||
[% pair.value -%] | ||
[% END -%] | ||
[% END %] | ||
[% END -%] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
Match[% -%] | ||
[% FOREACH pair IN mt.criteria.pairs -%] | ||
[% IF pair.value.is_boolean -%] | ||
[% pair.key -%] | ||
[% ELSE -%] | ||
[% pair.key %] [% CCM.is_list(pair.value) ? pair.value.join(',') : pair.value -%] | ||
[% END -%] | ||
[% END -%] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,29 +5,43 @@ include 'pan/types'; | |
# rename these types to prevent conflicts | ||
# we will remove these in an upcoming pr after template-library-core | ||
# has been updated with the new types from ncm-ssh | ||
type temp_ssh_ciphers = string with match (SELF, "^((blowfish|3des|aes128|aes192|aes256|cast128)-cbc" + | ||
"|(aes128|aes192|aes256)-ctr|arcfour|arcfour(128|256)|(aes128-gcm|aes256-gcm|chacha20-poly1305)@openssh.com)$"); | ||
type temp_ssh_hostkeyalgorithms = string with match(SELF, "^(ssh-(rsa|dss|ed25519)|ecdsa-sha2-nistp(256|384|521)|" + | ||
"(ssh-rsa-cert-v01|ssh-dss-cert-v01|ecdsa-sha2-nistp256-cert-v01|ecdsa-sha2-nistp384-cert-v01|" + | ||
"ecdsa-sha2-nistp521-cert-v01|ssh-rsa-cert-v00|ssh-dss-cert-v00|ssh-ed25519-cert-v01)@openssh.com)$"); | ||
type temp_ssh_ciphers = string with match (SELF, "^[+-]?(" + | ||
"(blowfish|3des|aes(128|192|256)|cast128)-cbc" + | ||
"|aes(128|192|256)-ctr|arcfour|arcfour(128|256)" + | ||
"|(aes(128|256)-gcm|chacha20-poly1305)@openssh.com)$"); | ||
type temp_ssh_hostkeyalgorithms = string with match(SELF, "^[+-]?(" + | ||
"ssh-(rsa|dss|ed25519)|ecdsa-sha2-nistp(256|384|521)|" + | ||
"(ssh-rsa-cert-v0[01]|ssh-dss-cert-v01|ecdsa-sha2-nistp(256|384|521)-cert-v01|" + | ||
"ssh-dss-cert-v00|ssh-ed25519-cert-v01)@openssh.com)$"); | ||
type temp_ssh_kbdinteractivedevices = string with match (SELF, "^(bsdauth|pam|skey)$"); | ||
type temp_ssh_kexalgorithms = string with match (SELF, "^(diffie-hellman-group(1-sha1|14-sha1|-exchange-sha1|" + | ||
"-exchange-sha256)|ecdh-sha2-nistp(256|384|521)|[email protected]|gss-gex-sha1-|" + | ||
"gss-group1-sha1-|gss-group14-sha1-)$"); | ||
type temp_ssh_MACs = string with match(SELF, "^(hmac-(sha1|sha1-96|sha2-256|sha2-512|md5|md5-96|ripemd160)|" + | ||
# Recent versions have distinct GSSAPIKexAlgorithms | ||
type temp_ssh_gss_kexalgorithms = string with match (SELF, "^[+-]?(gss-(gex|group1|group14)-sha1-" + | ||
"|gss-group14-sha256-|gss-group16-sha512-|gss-nistp256-sha256-|gss-curve25519-sha256-)$"); | ||
# Older versions include GSSAPI mechanisms in KEXAlgorithms, but only the SHA1 variants | ||
type temp_ssh_kexalgorithms = string with match (SELF, "^[+-]?(" + | ||
"diffie-hellman-group(1-sha1|14-sha1|-exchange-sha1|-exchange-sha256)" + | ||
"|ecdh-sha2-nistp(256|384|521)|[email protected]" + | ||
"|gss-(gex|group1|group14)-sha1-)$"); | ||
type temp_ssh_MACs = string with match(SELF, "^[+-]?(hmac-(sha1|sha1-96|sha2-256|sha2-512|md5|md5-96|ripemd160)|" + | ||
"(hmac-ripemd160|umac-64|umac-128|hmac-sha1-etm|hmac-sha1-96-etm|hmac-sha2-256-etm|hmac-sha2-512-etm|" + | ||
"hmac-md5-etm|hmac-md5-96-etm|hmac-ripemd160-etm|umac-64-etm|umac-128-etm)@openssh.com)$"); | ||
type temp_ssh_CAAlgorithms = string with match(SELF, "^[+-]?(" + | ||
"ecdsa-sha2-nistp(256|384|521)|ssh-ed25519|rsa-sha2-(256|512)|ssh-rsa)$"); | ||
|
||
|
||
type ssh_config_opts = { | ||
'AddKeysToAgent' ? string with match (SELF, "^(yes|no|ask|confirm)$") | ||
'AddressFamily' ? string with match (SELF, "^(any|inet|inet6)$") | ||
'BatchMode' ? boolean | ||
'BindAddress' ? string | ||
'BindInterface' ? string | ||
'CanonicalDomains' ? string[] | ||
'CanonicalizeFallbackLocal' ? boolean | ||
'CanonicalizeHostname' ? string with match (SELF, "^(yes|no|always)$") | ||
'CanonicalizeMaxDots' ? long(0..) | ||
'CanonicalizePermittedCNAMEs' ? string[] | ||
'CASignatureAlgorithms' ? temp_ssh_CAAlgorithms[] | ||
'CertificateFile' ? string[] | ||
'ChallengeResponseAuthentication' ? boolean | ||
'CheckHostIP' ? boolean | ||
'Cipher' ? string with match (SELF, "^(blowfish|3des|des)$") | ||
|
@@ -52,16 +66,24 @@ type ssh_config_opts = { | |
'GatewayPorts' ? boolean | ||
'GlobalKnownHostsFile' ? string[] | ||
'GSSAPIAuthentication' ? boolean | ||
'GSSAPIClientIdentity' ? string | ||
'GSSAPIDelegateCredentials' ? boolean | ||
'GSSAPIKeyExchange' ? boolean | ||
'GSSAPIKexAlgorithms' ? temp_ssh_gss_kexalgorithms[] | ||
'GSSAPIRenewalForcesRekey' ? boolean | ||
'GSSAPIServerIdentity' ? string | ||
'GSSAPITrustDns' ? boolean | ||
'HashKnownHosts' ? boolean | ||
'HostbasedAuthentication' ? boolean | ||
'HostbasedKeyTypes' ? string[] | ||
'HostKeyAlgorithms' ? temp_ssh_hostkeyalgorithms[] | ||
'HostKeyAlias' ? string | ||
'HostName' ? string | ||
'IdentitiesOnly' ? boolean | ||
'IdentityAgent' ? string | ||
'IdentityFile' ? string[] | ||
'IgnoreUnknown' ? string[] | ||
'Include' ? string[] | ||
'IPQoS' ? string with match (SELF, "^(af[1234][123]|cs[0-7]|ef|lowdelay|throughput|reliability)$") | ||
'KbdInteractiveAuthentication' ? boolean | ||
'KbdInteractiveDevices' ? temp_ssh_kbdinteractivedevices[] | ||
|
@@ -79,9 +101,12 @@ type ssh_config_opts = { | |
'PreferredAuthentications' ? string[] | ||
'Protocol' ? long(1..2) | ||
'ProxyCommand' ? string | ||
'ProxyJump' ? string[] | ||
'ProxyUseFdpass' ? boolean | ||
'PubkeyAcceptedKeyTypes' ? temp_ssh_hostkeyalgorithms[] | ||
'PubkeyAuthentication' ? boolean | ||
'RekeyLimit' ? string | ||
'RemoteCommand' ? string | ||
'RemoteForward' ? string | ||
'RequestTTY' ? string with match (SELF, "^(yes|no|force|auto)$") | ||
'RevokedHostKeys' ? string[] | ||
|
@@ -90,9 +115,11 @@ type ssh_config_opts = { | |
'SendEnv' ? string[] | ||
'ServerAliveCountMax' ? long(0..) | ||
'ServerAliveInterval' ? long(0..) | ||
'SetEnv' ? string{} | ||
'StreamLocalBindMask' ? string | ||
'StreamLocalBindUnlink' ? boolean | ||
'StrictHostKeyChecking' ? string with match (SELF, "^(yes|no|ask)$") | ||
'SyslogFacility' ? string with match(SELF, "^(DAEMON|USER|AUTH(PRIV)?|LOCAL[0-7])$") | ||
'TCPKeepAlive' ? boolean | ||
'Tunnel' ? string with match (SELF, "^(yes|no|point-to-point|ethernet)$") | ||
'TunnelDevice' ? string | ||
|
@@ -108,13 +135,27 @@ type ssh_config_opts = { | |
type ssh_config_host = { | ||
"hostnames" : string[] | ||
include ssh_config_opts | ||
}; | ||
|
||
type ssh_config_match_criteria = { | ||
"all" ? boolean with SELF | ||
"canonical" ? boolean with SELF | ||
"final" ? boolean with SELF | ||
"user" ? string[] | ||
"localuser" ? string[] | ||
"host" ? string[] | ||
"originalhost" ? string[] | ||
"exec" ? string | ||
} with { | ||
if (exists(SELF['all']) && length(SELF) > 1) { | ||
error('You can only set all, no other options allowed'); | ||
}; | ||
true; | ||
}; | ||
|
||
type ssh_config_match = { | ||
"matches" : string[] | ||
"criteria" : ssh_config_match_criteria with length(SELF) > 0 | ||
include ssh_config_opts | ||
|
||
}; | ||
|
||
type ssh_config_file = { | ||
|
@@ -123,3 +164,130 @@ 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_criteria = { | ||
"All" ? boolean with SELF | ||
"User" ? string[] | ||
"Group" ? string[] | ||
"Host" ? string[] | ||
"LocalAddress" ? string[] | ||
"LocalPort" ? string[] | ||
"RDomain" ? string[] | ||
"Address" ? string[] | ||
} with { | ||
if (exists(SELF['All']) && length(SELF) > 1) { | ||
error('You can only set All, no other options allowed'); | ||
}; | ||
true; | ||
}; | ||
|
||
type sshd_config_match = { | ||
"criteria" : sshd_config_match_criteria with length(SELF) > 0 | ||
include sshd_config_match_opts | ||
}; | ||
|
||
type sshd_config_opts = { | ||
include sshd_config_match_opts | ||
'AddressFamily' ? string with match (SELF, "^(any|inet|inet6)$") | ||
'CASignatureAlgorithms' ? temp_ssh_CAAlgorithms[] | ||
'ChallengeResponseAuthentication' ? boolean | ||
'Ciphers' ? temp_ssh_ciphers[] | ||
'Compression' ? boolean | ||
'DisableForwarding' ? boolean | ||
'ExposeAuthInfo' ? boolean | ||
'FingerprintHash' ? string with match (SELF, "^(md5|sha256)$") | ||
'GSSAPICleanupCredentials' ? boolean | ||
'GSSAPIKeyExchange' ? boolean | ||
'GSSAPIKexAlgorithms' ? temp_ssh_gss_kexalgorithms[] | ||
'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 | ||
}; |
14 changes: 14 additions & 0 deletions
14
ncm-metaconfig/src/main/metaconfig/ssh/pan/server_config.pan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
unique template metaconfig/ssh/server_config; | ||
|
||
include 'metaconfig/ssh/schema'; | ||
|
||
bind "/software/components/metaconfig/services/{/etc/ssh/sshd_config}/contents" = sshd_config_file; | ||
|
||
# since final locks the whole path, bind it to a fix value and set it as default too | ||
bind "/software/components/metaconfig/commands/sshd_test_stdin" = | ||
string = "/usr/sbin/sshd -t -f /dev/stdin" with SELF == "/usr/sbin/sshd -t -f /dev/stdin"; | ||
|
||
prefix "/software/components/metaconfig/services/{/etc/ssh/sshd_config}"; | ||
"module" = "ssh/server"; | ||
"actions/test" = "sshd_test_stdin"; | ||
"daemons/sshd" = "restart"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 -%] | ||
[% INCLUDE metaconfig/ssh/match.tt %] | ||
[% INCLUDE metaconfig/ssh/server_attrs.tt data=mt FILTER indent %] | ||
[% END -%] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
[% # different forms of list handling, default for list type is space separated | ||
commalist = ['Ciphers', 'HostKeyAlgorithms', 'HostbasedAcceptedKeyTypes', 'KexAlgorithms', 'MACs', 'PubkeyAcceptedKeyTypes' ]; | ||
multilinelist = ['HostKey', 'ListenAddress', 'Port' ] | ||
-%] | ||
[%- FOREACH pair IN data.pairs -%] | ||
[% SWITCH pair.key -%] | ||
[% CASE 'criteria' %][% # do nothing -%] | ||
[% 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 %] [% -%] | ||
[% IF pair.value.is_boolean -%] | ||
[% pair.value ? 'yes' : 'no' -%] | ||
[% ELSIF CCM.is_list(pair.value) -%] | ||
[% pair.value.join(' ') -%] | ||
[% ELSE -%] | ||
[% pair.value -%] | ||
[% END -%] | ||
[% END %] | ||
[% END -%] |
Oops, something went wrong.