2020-09-27 03:23:58 -04:00
|
|
|
/*
|
|
|
|
SSHSecure - a program to harden OpenSSH from defaults
|
|
|
|
Copyright (C) 2020 Brent Saner
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package config
|
|
|
|
|
|
|
|
const (
|
|
|
|
// To check if this release of SSHSecure is up-to-date with the default values.
|
|
|
|
// upstreamSshdURL string = "https://anongit.mindrot.org/openssh.git/plain/sshd_config"
|
|
|
|
upstreamSshdURL string = "https://raw.githubusercontent.com/openssh/openssh-portable/master/sshd_config"
|
|
|
|
upstreamSshdCksum string = "952C844D7B36C54B03E2ADFB24860405" +
|
|
|
|
"1A702620A0ADC0738A8C30DC83D42A75" +
|
|
|
|
"27F5B3C184E779B1430168950F7695A1" +
|
|
|
|
"AA249F7CC719DEC1631ACFDDC2E8B653"
|
|
|
|
// upstreamSshURL string = "https://anongit.mindrot.org/openssh.git/plain/ssh_config"
|
|
|
|
upstreamSshURL string = "https://raw.githubusercontent.com/openssh/openssh-portable/master/ssh_config"
|
|
|
|
upstreamSshCksum string = "FF2D600465CC5D9CFBB57346491CCAF2" +
|
|
|
|
"C917E2F0C7B4D4EF6B851940948B55BD" +
|
|
|
|
"88205AC8153210ECA6C6BEA38E800F33" +
|
|
|
|
"7562C0190AE760220417A5DC2E00A5E1"
|
|
|
|
)
|
|
|
|
|
|
|
|
// These are items that this program modifies.
|
|
|
|
var (
|
|
|
|
// sshdModify are values we modify.
|
|
|
|
sshdModify = [...]string{
|
2020-10-07 11:25:56 -04:00
|
|
|
"AuthenticationMethods",
|
|
|
|
"ChallengeResponseAuthentication",
|
|
|
|
"Ciphers",
|
2020-09-27 03:23:58 -04:00
|
|
|
"HostKey",
|
2020-10-07 11:25:56 -04:00
|
|
|
"HostKeyAlgorithms",
|
|
|
|
"KexAlgorithms",
|
|
|
|
"MACs",
|
2020-09-27 03:23:58 -04:00
|
|
|
"PasswordAuthentication",
|
|
|
|
"PermitEmptyPasswords",
|
2020-10-07 11:25:56 -04:00
|
|
|
"PermitRootLogin",
|
|
|
|
"PrintLastLog",
|
2020-09-27 03:23:58 -04:00
|
|
|
"Protocol",
|
2020-10-07 11:25:56 -04:00
|
|
|
"PubkeyAuthentication",
|
|
|
|
"StrictModes",
|
2020-09-27 03:23:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// sshModify are values we modify.
|
|
|
|
sshModify = [...]string{""}
|
|
|
|
)
|
|
|
|
|
|
|
|
// These are collections of long lists of valid values.
|
|
|
|
var (
|
|
|
|
// sshdMulti are values that can be specified multiple times (multiple lines).
|
|
|
|
sshdMulti = [...]string{
|
|
|
|
"",
|
|
|
|
}
|
|
|
|
|
2020-10-07 11:25:56 -04:00
|
|
|
sshMulti = [...]string{
|
|
|
|
"IdentityFile",
|
|
|
|
}
|
|
|
|
|
2020-09-27 03:23:58 -04:00
|
|
|
// authMethods are authentication methods that openssh supports.
|
|
|
|
authMethods = []string{
|
|
|
|
"any",
|
|
|
|
"keyboard-interactive",
|
|
|
|
"keyboard-interactive:bsdauth",
|
|
|
|
"keyboard-interactive:pam",
|
|
|
|
"gssapi-with-mic",
|
|
|
|
"hostbased",
|
|
|
|
"none",
|
|
|
|
"password",
|
|
|
|
"publickey",
|
|
|
|
}
|
|
|
|
|
|
|
|
// ciphers are cipher algorithms that openssh supports.
|
|
|
|
ciphers = []string{
|
|
|
|
"3des-cbc",
|
|
|
|
"aes128-cbc",
|
|
|
|
"aes192-cbc",
|
|
|
|
"aes256-cbc",
|
|
|
|
"aes128-ctr",
|
|
|
|
"aes192-ctr",
|
|
|
|
"aes256-ctr",
|
|
|
|
"aes128-gcm@openssh.com",
|
|
|
|
"aes256-gcm@openssh.com",
|
|
|
|
"chacha20-poly1305@openssh.com",
|
|
|
|
}
|
|
|
|
|
|
|
|
// forwardAllows are shared values used by forwarding access control.
|
|
|
|
forwardAllows = []string{"yes", "all", "no", "local", "remote"}
|
|
|
|
|
2020-10-07 11:25:56 -04:00
|
|
|
// keyTypes are algorithms/types used for host keys and client pubkeys.
|
2020-09-27 03:23:58 -04:00
|
|
|
// The following should generate the same list.
|
|
|
|
// ssh -Q HostKeyAlgorithms | sed -re 's/^/"/g' -e 's/$/",/g'
|
|
|
|
// ssh -Q HostbasedAcceptedKeyTypes | sed -re 's/^/"/g' -e 's/$/",/g'
|
2020-10-07 11:25:56 -04:00
|
|
|
// ssh -Q PubkeyAcceptedKeyTypes | sed -re 's/^/"/g' -e 's/$/",/g'
|
|
|
|
// ssh -Q HostbasedKeyTypes | sed -re 's/^/"/g' -e 's/$/",/g'
|
|
|
|
keyTypes = []string{
|
2020-09-27 03:23:58 -04:00
|
|
|
"ssh-ed25519",
|
|
|
|
"ssh-ed25519-cert-v01@openssh.com",
|
|
|
|
"sk-ssh-ed25519@openssh.com",
|
|
|
|
"sk-ssh-ed25519-cert-v01@openssh.com",
|
|
|
|
"ssh-rsa",
|
|
|
|
"rsa-sha2-256",
|
|
|
|
"rsa-sha2-512",
|
|
|
|
"ssh-dss",
|
|
|
|
"ecdsa-sha2-nistp256",
|
|
|
|
"ecdsa-sha2-nistp384",
|
|
|
|
"ecdsa-sha2-nistp521",
|
|
|
|
"sk-ecdsa-sha2-nistp256@openssh.com",
|
|
|
|
"ssh-rsa-cert-v01@openssh.com",
|
|
|
|
"rsa-sha2-256-cert-v01@openssh.com",
|
|
|
|
"rsa-sha2-512-cert-v01@openssh.com",
|
|
|
|
"ssh-dss-cert-v01@openssh.com",
|
|
|
|
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
|
|
|
"ecdsa-sha2-nistp384-cert-v01@openssh.com",
|
|
|
|
"ecdsa-sha2-nistp521-cert-v01@openssh.com",
|
|
|
|
"sk-ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
|
|
|
}
|
|
|
|
|
|
|
|
// ipQoS is a list of valid QoS profiles.
|
|
|
|
ipQoS = []string{
|
|
|
|
// This also supports a "numeric value" per sshd_config(5),
|
|
|
|
// but I have no idea what those values are, their range, etc.
|
|
|
|
// So strings only. Makes for more readable configs anyways.
|
|
|
|
// TODO: is this specified in the source anywhere?
|
|
|
|
"af11",
|
|
|
|
"af12",
|
|
|
|
"af13",
|
|
|
|
"af21",
|
|
|
|
"af22",
|
|
|
|
"af23",
|
|
|
|
"af31",
|
|
|
|
"af32",
|
|
|
|
"af33",
|
|
|
|
"af41",
|
|
|
|
"af42",
|
|
|
|
"af43",
|
|
|
|
"cs0",
|
|
|
|
"cs1",
|
|
|
|
"cs2",
|
|
|
|
"cs3",
|
|
|
|
"cs4",
|
|
|
|
"cs5",
|
|
|
|
"cs6",
|
|
|
|
"cs7",
|
|
|
|
"ef",
|
|
|
|
"le",
|
|
|
|
"lowdelay",
|
|
|
|
"throughput",
|
|
|
|
"reliability",
|
|
|
|
"none",
|
|
|
|
}
|
|
|
|
|
|
|
|
// kexAlgos is a lost of valid kex ("KEy eXchange") algorithms.
|
|
|
|
// ssh -Q kex | sed -re 's/^/"/g' -e 's/$/",/g'
|
|
|
|
kexAlgos = []string{
|
|
|
|
"diffie-hellman-group1-sha1",
|
|
|
|
"diffie-hellman-group14-sha1",
|
|
|
|
"diffie-hellman-group14-sha256",
|
|
|
|
"diffie-hellman-group16-sha512",
|
|
|
|
"diffie-hellman-group18-sha512",
|
|
|
|
"diffie-hellman-group-exchange-sha1",
|
|
|
|
"diffie-hellman-group-exchange-sha256",
|
|
|
|
"ecdh-sha2-nistp256",
|
|
|
|
"ecdh-sha2-nistp384",
|
|
|
|
"ecdh-sha2-nistp521",
|
|
|
|
"curve25519-sha256",
|
|
|
|
"curve25519-sha256@libssh.org",
|
|
|
|
"sntrup4591761x25519-sha512@tinyssh.org",
|
|
|
|
}
|
|
|
|
|
|
|
|
// sigAlgos is a list of valid algorithms for CA signatures.
|
|
|
|
sigAlgos = []string{
|
|
|
|
// These are the defaults. TODO: are any others valid?
|
|
|
|
"ecdsa-sha2-nistp256",
|
|
|
|
"ecdsa-sha2-nistp384",
|
|
|
|
"ecdsa-sha2-nistp521",
|
|
|
|
"ssh-ed25519",
|
|
|
|
"rsa-sha2-512",
|
|
|
|
"rsa-sha2-256",
|
|
|
|
"ssh-rsa",
|
|
|
|
}
|
|
|
|
|
|
|
|
// logLevels is a list of valid LogLevel levels.
|
|
|
|
logLevels = []string{
|
|
|
|
"QUIET",
|
|
|
|
"FATAL",
|
|
|
|
"ERROR",
|
|
|
|
"INFO", // default
|
|
|
|
"VERBOSE",
|
|
|
|
"DEBUG", // same as DEBUG1
|
|
|
|
"DEBUG1", // same as DEBUG
|
|
|
|
"DEBUG2",
|
|
|
|
"DEBUG3",
|
|
|
|
}
|
|
|
|
|
2020-10-07 11:25:56 -04:00
|
|
|
// logFacilities is a list of valid syslog facilities.
|
|
|
|
logFacilities = []string{
|
|
|
|
"DAEMON",
|
|
|
|
"USER",
|
|
|
|
"AUTH", // default
|
|
|
|
"LOCAL0",
|
|
|
|
"LOCAL1",
|
|
|
|
"LOCAL2",
|
|
|
|
"LOCAL3",
|
|
|
|
"LOCAL4",
|
|
|
|
"LOCAL5",
|
|
|
|
"LOCAL6",
|
|
|
|
"LOCAL7",
|
|
|
|
}
|
|
|
|
|
2020-09-27 03:23:58 -04:00
|
|
|
// macAlgos is a list of valid MAC (Message Authentication Code) values. "-etm" algos are recommended by upstream.
|
|
|
|
// ssh -Q mac | sed -re 's/^/"/g' -e 's/$/",/g'
|
|
|
|
macAlgos = []string{
|
|
|
|
"hmac-sha1",
|
|
|
|
"hmac-sha1-96",
|
|
|
|
"hmac-sha2-256",
|
|
|
|
"hmac-sha2-512",
|
|
|
|
"hmac-md5",
|
|
|
|
"hmac-md5-96",
|
|
|
|
"umac-64@openssh.com",
|
|
|
|
"umac-128@openssh.com",
|
|
|
|
"hmac-sha1-etm@openssh.com",
|
|
|
|
"hmac-sha1-96-etm@openssh.com",
|
|
|
|
"hmac-sha2-256-etm@openssh.com",
|
|
|
|
"hmac-sha2-512-etm@openssh.com",
|
|
|
|
"hmac-md5-etm@openssh.com",
|
|
|
|
"hmac-md5-96-etm@openssh.com",
|
|
|
|
"umac-64-etm@openssh.com",
|
|
|
|
"umac-128-etm@openssh.com",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// This is a collection related to Match blocks.
|
|
|
|
var (
|
|
|
|
// sshdMatchCriteria is a list of valid criteria that can be used in a Match block.
|
|
|
|
// Valid keys for sshdMatchCriteria are tracked via field names in SshdMatchRule.
|
|
|
|
// Multiple criteria can be specified by e.g. "Match User foo, Host bar.tld"
|
|
|
|
sshdMatchCriteria = []string{
|
2020-10-07 11:25:56 -04:00
|
|
|
"Address",
|
2020-09-27 03:23:58 -04:00
|
|
|
"All",
|
|
|
|
"User",
|
|
|
|
"Group",
|
|
|
|
"Host",
|
|
|
|
"LocalAddress",
|
|
|
|
"LocalPort",
|
|
|
|
"RDomain",
|
2020-10-07 11:25:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// sshMatchCriteria is a list of valid criteria that can be used in a Match or Host block.
|
|
|
|
// Valid keys for sshMatchCriteria are tracked via field names in SshMatchRule.
|
|
|
|
// Multiple criteria can be specified by e.g. "Match User foo, Host bar.tld"
|
|
|
|
sshMatchCriteria = []string{
|
|
|
|
"all", // Must appear alone, or immediately after canonical/final.
|
|
|
|
"canonical",
|
|
|
|
"exec", // Requires second argument.
|
|
|
|
"final",
|
|
|
|
"host", // Requires second argument.
|
|
|
|
"localuser", // Requires second argument.
|
|
|
|
"originalhost", // Requires second argument.
|
|
|
|
"user", // Requires second argument.
|
2020-09-27 03:23:58 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// The following are validator maps.
|
|
|
|
var (
|
|
|
|
// These directives can also begin with "+", "-", or "^", so they need to be stripped off.
|
2020-10-07 11:25:56 -04:00
|
|
|
// TODO: How to do this non-destructively and cleanly?
|
|
|
|
// Currently we just save the struct field's first item with the prefix and strip it in a local var for validating.
|
2020-09-27 03:23:58 -04:00
|
|
|
sshdStripPre = []string{
|
|
|
|
"HostbasedAcceptedKeyTypes",
|
|
|
|
"KexAlgorithms",
|
|
|
|
}
|
2020-10-07 11:25:56 -04:00
|
|
|
sshStripPre = []string{
|
|
|
|
"HostbasedKeyTypes",
|
|
|
|
"KexAlgorithms",
|
|
|
|
}
|
|
|
|
|
2020-09-27 03:23:58 -04:00
|
|
|
// validSshdSingleVals are values that can accept a single string value from a static list.
|
|
|
|
validSshdSingleVals = map[string][]string{
|
|
|
|
"AddressFamily": {"any", "inet", "inet6"},
|
|
|
|
"AllowStreamLocalForwarding": forwardAllows,
|
|
|
|
"AllowTcpForwarding": forwardAllows,
|
|
|
|
"Compression": {"yes", "delayed", "no"}, // "delayed" is legacy, same as "yes".
|
|
|
|
"FingerprintHash": {"sha256", "md5"},
|
|
|
|
"GatewayPorts": {"yes", "no", "clientspecified"},
|
2020-10-07 11:25:56 -04:00
|
|
|
"HostbasedAcceptedKeyTypes": keyTypes,
|
2020-09-27 03:23:58 -04:00
|
|
|
"IgnoreRHosts": {"yes", "shosts-only", "no"},
|
|
|
|
"LogLevel": logLevels,
|
2020-10-07 11:25:56 -04:00
|
|
|
"PermitRootLogin": {"yes", "prohibit-password", "forced-commands-only", "no"}, // "without-password" is deprecated.
|
|
|
|
"PermitTunnel": {"yes", "point-to-point", "ethernet", "no"},
|
|
|
|
"PubkeyAuthOptions": {"none", "touch-required"},
|
|
|
|
"SyslogFacility": logFacilities,
|
2020-09-27 03:23:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// validSshdMultiVals are values that can accept multiple values from a static list.
|
|
|
|
validSshdMultiVals = map[string][]string{
|
|
|
|
"AuthenticationMethods": authMethods,
|
|
|
|
"CASignatureAlgorithms": sigAlgos,
|
|
|
|
"Ciphers": ciphers,
|
2020-10-07 11:25:56 -04:00
|
|
|
"HostbasedAcceptedKeyTypes": keyTypes,
|
|
|
|
"HostKeyAlgorithms": keyTypes,
|
|
|
|
"KexAlgorithms": kexAlgos,
|
2020-09-27 03:23:58 -04:00
|
|
|
"MACs": macAlgos,
|
2020-10-07 11:25:56 -04:00
|
|
|
"PubkeyAcceptedKeyTypes": keyTypes,
|
|
|
|
}
|
|
|
|
|
|
|
|
// validSshSingleVals are values that can accept a single string value from a static list.
|
|
|
|
validSshSingleVals = map[string][]string{
|
|
|
|
"AddKeysToAgent": {"yes", "ask", "confirm", "no"},
|
|
|
|
"AddressFamily": {"any", "inet", "inet6"},
|
|
|
|
"ControlMaster": {"ask", "yes", "no", "autoask", "auto"},
|
|
|
|
"FingerprintHash": {"sha256", "md5"},
|
|
|
|
}
|
|
|
|
|
|
|
|
// validSshMultiVals are values that can accept multiple values from a static list.
|
|
|
|
validSshMultiVals = map[string][]string{
|
|
|
|
"CASignatureAlgorithms": sigAlgos,
|
|
|
|
"Ciphers": ciphers,
|
|
|
|
"HostbasedKeyTypes": keyTypes,
|
|
|
|
"HostKeyAlgorithms": keyTypes,
|
|
|
|
"KbdInteractiveDevices": {"bsdauth", "pam"},
|
|
|
|
"KexAlgorithms": kexAlgos,
|
2020-09-27 03:23:58 -04:00
|
|
|
}
|
|
|
|
)
|