How to allow only certain users to login to an SSH server from a particular network interface?


  • eth0 is "outside", eth1 is "inside".
  • user1 is trusted to login from anywhere
  • user2 is only allowed to login from "inside"

Can't use AllowUsers user1@eth0 because AllowUsers takes a hostname not an interface name.

Other answers on this site suggest something like:

Match address # eth0's network
   AllowUsers user1
Match address # eth1's network
   AllowUsers user1,user2
Match address  # Match's equivalent of a closing brace?

However if eth0 is using a DHCP server to get its address, then it doesn't know in advance that is the right address to put in sshd_config.

(OpenSSH on Ubuntu 12.04 if that makes a difference)

  • In fact, AllowUsers isn't even a valid thing to put inside a Match block according to sshd_config's manual – OJW Feb 14 '13 at 13:42

I don't know how to do this in a Match block, and your comment above suggests it's not possible (as does, as you note, the man page).

But if you're sure that you want to do the user restriction by interface - which your questions says you do - you could run two sshds, each having a different sshd_config which directs it to listen on one interface only, controlled by the ListenAddress directive.

The sshd listening on the internal interface could in its config have AllowUsers user1 user2, while that listening on the external interface could have AllowUsers user1. I'd probably do it by group membership and have AllowGroups internal / AllowGroups internal external instead, but that's just me.

Edit: imo, the right way to do this is to run /usr/sbin/sshd -f /etc/ssh/sshd_config_inside and /usr/sbin/sshd -f /etc/ssh/sshd_config_outside. Arranging how this works at boot time, and ensuring that your service startup/shutdown files do the right thing, is indeed important, but it is also a perfectly normal thing for a sysadmin to need to do, and to do. It is definitely not necessary to have two binaries, or even the same binary by two different names, to do this.

| improve this answer | |
  • My concern here is that typical instructions for running 2 x SSHD could leave you with a system where one of the SSH instances doesn't receive security updates from the distro's package manager. – OJW Feb 19 '13 at 11:38
  • 1
    You miss my point. Not two sets of binaries; one set of binaries, two sets of config files. Security updates very rarely touch config files, not least because it tends to break so many people's customisations. – MadHatter Feb 19 '13 at 11:52
  • I was looking at fixunix.com/ssh/… which suggests "ln -s /bin/othersshd /bin/sshd" as if it needed two different names for the executable -- using the same actual file sounds like a good start, but the updater might be doing a "killall -s HUP sshd" or "service restart sshd" and miss one of them. – OJW Feb 19 '13 at 11:59
  • 2
    @OJW There's no point to using a different binary, or even a symbolic link. Using a different configuration file is the important part here. – Michael Hampton Feb 19 '13 at 15:49
  • @OJW and make sure you have two init-scripts that do start/stop/status for this specific instance. Most OS-supplied scripts will have to be modified to take two different instances into account (and you need two of them - of course). If you need to modify the sshd-init-script, make two copies and disable the original, since it will be changed by sshd-updates (which would break your modifications). – Nils Feb 22 '13 at 21:44

I know this is an old question but I was looking for a solution without having to start 2 instances of sshd.

Referring to your specific question and the subnet and the subnet, you could use the following:

AllowUsers user1@1.2.* user1@2.3.* user2@2.3.*

Reference: http://www.unixlore.net/articles/five-minutes-to-even-more-secure-ssh.html

For my network, I use the following to allow user chris to ssh from anywhere but only allow user1, user2 and user3 to ssh on my internal network (

AllowUsers chris user1@192.168.0.* user2@192.168.0.* user3@192.168.0.*

Version: SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.3 on Ubuntu 14.04.3 LTS

| improve this answer | |

Match address is invalid, must be Match address The network addresses of the interfaces don't change, do they? So it doesn't matter what IP you get.

Another option may be (I have no personal experience with that) to create two virtual interfaces with a static address, have two sshd instances, each bound to one of these addresses only and make DNAT from the DHCP interface to the virtual one.

| improve this answer | |
  • yes, some of the network addresses can change. e.g. an appliance that's preconfigured such that it can be connected into any "outside" network with a DHCP server. – OJW Feb 14 '13 at 13:18
  • I am not talking about moved devices. Your internal interface is connected to a certain DHCP server via a switch and this DHCP server gives all devices an address from, doesn't it? Do you have to be afraid that your internal interface is today and will be tomorrow? Probably not. So whatever connects from comes in via the internal interface. – Hauke Laging Feb 14 '13 at 13:26

Maybe you could write a small script to get the current eth0 address (from ifconfig?) and to set in your sshd_config (using sed); if I remember correctly it's also possible to write hook scripts to be executed everytime an ethernet interface goes down/up (this could solve the necessity to update manually or via crontab you sshd_config file).

| improve this answer | |
  • Or, is there any good reason why you can't set a static address on the 'inside' interface? – chrskly Feb 14 '13 at 13:08
  • chrskly could be along the right lines here - one way of identifying the outside network could be "a rule which doesn't match any of the known inside networks" – OJW Feb 14 '13 at 13:20

Match Adress and Match User should work and since a couple of months, since OpenSSH 7.7, at least if you believe the bug reports here you can also have negating matches.

If you want to lock down your SSH with sshd_config, the caveat is that you should disable password and pubkey based logins for anyone else.

For example:

  • allow root access only from inside (, pivate "office" range)
  • allow a special user access from VPN (, private "VPN" range)
  • allow only pub-key access for other unprivileged users from anywhere, doesn't matter if inside or outside or in VPN


PasswordAuthentication no   #
PubkeyAuthentication no     # to disable access for all other users
Match Address
        PermitRootLogin yes
        PasswordAuthentication yes
        PubkeyAuthentication yes

Match User vpnuser Address
        PasswordAuthentication yes
        PubkeyAuthentication yes

Match User sarah peter robert Address *
        PasswordAuthentication no
        PubkeyAuthentication yes

This way, it doesn't matter how many interfaces your server has and which DHCP address they get - it matters where the users are connecting from, which is what should concern you.

| improve this answer | |

The short answer: You can't.

The long answer: You shan't.

It's only a pseudo-gain in terms of security. You should think over you security concept first.

But, in interest of professional discussion, you can with fugly hacks:

  1. Wait until you got your DHCP IPs (Yikes! I wouldn't do non-static on a server)
  2. Configure two different sshd's with the appropiate ListenAddress'es, assigning each of them a different set of allowed users as well. (edit: Has been described in the other answers here)
  3. Start the two separate daemons.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.