I have a home server with some SSH accounts that have weak passwords. Since we only used it locally, that's not that big a problem.

Now I want to allow external access from only one account, but still local access from the others. But this doesn't work (because only a subset of options is allowed in matches):

AllowUsers externaluser
Match Address
AllowGroups localusers

What's the best way to emulate this? (or should I just allow the local users external access, too, but without password auth, hoping they keep their private keys private?)

3 Answers 3


Maybe pam_access would be a better way to do this?

eg: in /etc/security/access.conf, do lines like:

    + : root : 192.168.0.
    + : localonlygroup : 192.168.0.
    + : remoteuser: ALL
    - : ALL : ALL

Then make sure /etc/pam.d/sshd, around where there's probably a line like:

    account    required     pam_nologin.so

add another line like:

    account    required     pam_access.so
  • sorry for taking so long to accept, works nicely and I don't have to touch IPtables. I've added + : ALL : tty1 tty2 tty3 tty4 tty5 tty6 to the start though, to have a fallback, since there are examples for X and TTY, so I'm guessing it's always consulted…
    – pascal
    Jan 28, 2012 at 3:52
  • As I've noticed when a "disabled" user tries to log in, his password is first accepted and then user login is denied. So the access is blocked but still the bad guys have the possibility to scan for valid user/password combination which no good. Is there a way to move the authorization (pam access check) before the authentication?
    – moo
    Sep 23, 2015 at 9:45

It is possible to achieve exactly what you are trying!

One solution is to run two different sshd instances, one for external facing users and one for internal users. With some clever use of the iptables REDIRECT target, you can continue to allow people to connect to sshd on port 22, but depending on where they're coming from they'll get the appropriate instance. Something like:

# Connect inside users to "inside" sshd.
iptables -t nat -A PREROUTING -s -p tcp --dport 22 -j REDIRECT --to-ports 2200

# Connect out*emphasized text*side users to "outside" sshd.
iptables -t nat -A PREROUTING -s -p tcp --dport 22 -j REDIRECT --to-ports 2201

This presumes you have the inside sshd listening on port 2200 and the outside sshd listening on port 2201, and that each one is using an appropriately configured sshd_config file. Note also that for this to work you'll need:

iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 2200 -j ACCEPT
iptables -A INPUT -p tcp --dport 2201 -j ACCEPT

We do exactly this for some of our interactive login hosts and it works nicely.

  • If server has two interfaces - external and internal, iptables not needed at all! One sshd server just listen on one interface with ListenAddress external_ip, another sshd ListenAddress internal_ip
    – gapsf
    Jul 27, 2022 at 16:07
  • This iptables rules are simply do not work as expected: first nat rule just redirect ALL connections to one sshd, and second nat rule never hits since both match the same.
    – gapsf
    Jul 27, 2022 at 16:14
  • Second NAT rule must be iptables -t nat -A PREROUTING ! -s -p tcp --dport 22 -j REDIRECT --to-ports 2201
    – gapsf
    Jul 27, 2022 at 16:54

If not using user group is acceptable

AllowUsers externaluser@* *@192.168.0.*

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .