We have a VPS running on AWS, although generic solution is expected regardless of hosting vendor.

This VPS is acting as a Jump Box (running CentOS 6) for various other internal server such as SSH access to various other boxes (which are connected to the Jump Box thru reverse SSH). The Jump Box exposes random higher port for each service.

Is there a possibility to expose these higher ports only to the IP address which is currently SSH'ed into the Jump Box?

I was thinking about scanning output of who -a to filter the IP address and update the IPTABLES using a cronjob or maybe update the security group of AWS using API. But this approach seems sketchy. Any suggestions?

  • 1
    Something along the lines of portmap -l ... man portmap – RubberStamp Nov 10 '17 at 3:41
  • @RubberStamp Interesting! Checking... – user1263746 Nov 10 '17 at 4:07
  • 1
    Just out of curiosity, why is this necessary or desirable? What benefit does this provide? What security risk does it address? – igal Nov 15 '17 at 2:22
  • Combining the IP identification from this answer with the ability to run a script upon ssh connection recommended here it seems you could set up your IPTABLES upon connection .. provided you know the ports on the JumpBox you want to allow connection to... – Forty3 Nov 17 '17 at 23:01
  • @igal The idea is to have a robust security auth. We do not have control over the authentication of the servers behind the jumpbox, some of them have ssh with password auth, and web based login with no strong password policy. So the jumpbox with ssh cert login provides a stronger security and in case a user is to be removed, just removing the user from jumpbox removes complete access. (Unless someone managed to have a backdoor in the servers behind the jumpbox, trying to address that problem by having somekind of logging). – user1263746 Nov 18 '17 at 6:15

You could build the described system using iptables, ipset and pam_exec.

The idea is following: There is a separate chain containing rules to allow incoming traffic to these higher ports. Iptables INPUT chain contains an ipset rule matching your logged in hosts, jumping to the separate chain. On successful log in, a pam_exec runs a script (at PAM session open) adding the remote host's IP address to the ipset set, and similarly removes it when PAM session is closed.

Configuring IPTABLES and IPSET

Create a set for user's IP addresses. Since ipsets are not persistent, so you need to configure the set to be created on boot before iptables are restored.

ipset -N users hash:ip

Configure iptables. A new INPUT-users chain which will contain the rules to allow traffic for logged in users.

iptables -N INPUT-users

If the source address is in users set, jump to INPUT-users chain.

iptables -A INPUT -m set --match-set users src -j INPUT-users

Add relevant rules to INPUT-users chain. These rules will be used for traffic with source address matching your user's. For example to allow tcp port 16384:

iptables -A INPUT-users -p tcp --dport 16384

Configuring PAM

Create following scripts to be executed on pam session open/close. The IP address will be in PAM_RHOST environmental variable set by pam_exec.


ipset --exist --add users "$PAM_RHOST"


ipset --del users "$PAM_RHOST"

Then configure pam to use them for ssh sessions. Append to /etc/pam.d/sshd:

session optional    pam_exec.so type=open_session /etc/security/pam_exec-session_open
session optional    pam_exec.so type=close_session /etc/security/pam_exec-session_close


  • If your user has multiple ssh sessions open, closing any of them will remove the IP address from the ipset. To avoid this, you need to write some check for the session_close script to remove the IP address only if it is the last session remaining for the user.

  • Should your user connect behind NAT, after connecting anyone behind the same NAT will match the ipset rule (allowed access).

  • This is near perfect! – user1263746 Nov 19 '17 at 15:35

If you know your destination/port as you're initiating ssh connection

I would suggest, ideally, that you connect to JumpBox with something like ssh -L 8080: <JumpBox address> where you're seeking which is behind firewall/NAT but is accessible to JumpBox.

This creates a connection and binds to (localhost) such that if you open a browser (or some other software) on your client and connect to http://localhost:8080 your packets will be routed to as if you were accessing right from your JumpBox itself.

If port numbers/destinations cannot be known at [ssh] connection time

With the caveat that the client be configured to use a SOCKS/SOCKS5 proxy, you could provide access for connected clients to any resource accessible to the server:

Connect to your VPS using “Dynamic Forwarding”

  1. ssh -D 1080 <JumpBox address>
  2. Configure client's software to use SOCKS proxy server localhost:1080
  3. Connections via configured software will be tunneled such that it's like you're connecting to whatever destination from the JumpBox itself.

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.