SSH Login Options
On pfSense 2.1, I have SSH enabled, and am able to connect from with the LAN and WAN sides, either as root or as a locally created user, using passwords or auth_keys.
What I would like to end up with is: LAN-side users logging-in with passwords and WAN-side users logging-in (only) with auth_keys.
I have seen mention of an ssh_config option that will force auth_keys for ALL users, but that is too indiscriminate for my purposes.
I would also like to be able to limit which users can connect from LAN or WAN.
Even a definitive "it can't be done" would save me wasting any more time trying to make it work.
I would take a look at the sshdcond package
Lots and lots of stuff you could do with that. Not sure you can pick interface - but should be able to create a ACL that allows your local addresses to use password auth, etc.
Many thanks for the suggestion.
"Lots and lots of stuff you could do with that"
That could be an award winning understatement.
From what I can see, it certainly seems capable of granting the level of control I require over logins, IF I can work out how to turn WAN/LAN into host ranges.
Do you, or does anyone else reading this, happen to know, or know where I might usefully look to learn, how MATCH statements are evaluated?
For example, does the daemon execute the first MATCH that matches, and then skip to the end of the file, or does it try every MATCH in turn and thereby allow later MATCHes to over-ride earlier MATCHes? The MAN pages don't make this clear.
is it going:
or is it going:
I am not 100 percent, but I would have to think first rule wins - this is normally how any firewall or acl works. One you get a match, you stop processing the rest of the list.
Since you know what your internal networks are, I would think this would be the easy way to get those to match. And since external coming from wan would not match those - then some sort of wildcard match for what you want the wan users to do.
That does look like a useful package, I was not aware of it.
Seems like you can set a global rule of requiring authtype certificate and then set an additional match rule that includes you local subnet with authtypes certificate, interactive keyboard. Not tried it though.
I think I spoke too soon, as it now all appears to be unravelling:
The sshdcond package does not offer the AllowUsers and AllowGroups statements for inclusion within a MATCH block, even though it references sshd_config(5) which says that you can put AllowGroups within a MATCH block.
It may not be sshdcond's fault though since, if I download, hack and restore the pfSense config file to include AllowGroups within a MATCH block (taking advantage of the MATCH section syntax previously created by sshdcond), pfSense itself then drops a message in the logs:
php: sshd: The command '/usr/sbin/sshd' returned exit code '255', the output was '/etc/ssh/sshd_config line 17: Directive 'AllowGroups' is not allowed within a Match block'
How does one find out which version of sshd is running on a given installation of pfSense? Then to track down the correct man page and find out what I can really do…
I also suspect that there may be other issues with sshdcond interacting with pfSense since, after restoring the backup, /etc/ssh/sshd_config did not show the sshdcond lines until after I had been to the sshdcond confiruration page and saved a dummy edit to one of them. At least the conditions appear to survive a subsequent restart.
sshd_config might also be failing to recognise !192.268.1.0/24 as meaning anywhere but the LAN, 'cos it's letting me log in with a password (or as root) when it shouldn't.
On the other hand, it could all be down to operator incompetence.
Ok, I haven't tried this but….
Odd though reading the man page it looks like Allowgroups should be allowed in the match block. :-
Edit: But not in FreeBSD 8.3! http://www.freebsd.org/cgi/man.cgi?query=sshd_config&apropos=0&sektion=5&manpath=FreeBSD+8.3-RELEASE&arch=default&format=html
So in the global section of the file set Passwordauthentication = no then use match against local addresses and set Passwordauthentication to yes inside the match block. So file should look like:
PasswordAuthentication no Match Address 192.168.1.1/16 PasswordAuthentication yes
Does that look anything like the file generated?
Im not a fan of password auth to ssh, and would only ever suggest public key for any user that has access to ssh.
But since you only want to allow ssh with passwords on the lan - I have to agree with stephen here, it should be as simple as global prevent passwords and then a rule that says if from your local lan(s) networks allow password.
Three different heroes in one discussion, I'm honoured.
Steve, thanks for noting that FreeBSD differs from other versions of sshd, it's reassuring to know that I not going completely mad…
I would agree that a global prohibit to take care of the WAN, followed by a MATCH to grant extra permits on the LAN, would be a sensible route to pursue but, and this might be the $64000 newbie question, how can I edit the sshd_config file when it gets regenerated at every restart? (At least that's what it says in its header and it seems to match with observed behaviour).
The default values do not appear to be in the config.xml file, so I can't get at them there. Are they sourced from anywhere else that I might be able to reach? One feels that it ought to be possible, even if I haven't got the faintest idea where to start...
You can disable password login globally in System: Advanced: Admin Access:
How does that alter the sshd_config file?
I'd noticed that checkbox previously, but had misinterpreted its likely behaviour and steered well clear.
But, with it enabled, I'm certainly getting a bit closer to where I wanted to be, though it still leaves PermitRootLogin enabled globally. I had intended to disable Root from the WAN.
(It may well be that KeyAuthenticationOnly, when no-one has the key, is as hacker-proof as a total prohibition on RootLogin would be anyway).
I am, however, beginning to suspect that pfSense may not be correctly honouring MATHES of host addresses when given in the form "192.168.1.0/24" (as specified in the man pages you pointed me at) whilst it does accept "192.168.1.*". This may explain some, if not most, of my earlier confusion.
More news when I've done some more testing…