# Mininet-containernet 3 /SSH tunnel [TOC] Topology ![](https://hackmd.io/_uploads/HJbyUkMH2.png) ```python #!/usr/bin/python from mininet.net import Containernet from mininet.node import Docker from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.link import TCLink, Link def topology(): net = Containernet() info("adding Host\n") h1 = net.addHost('h1', ip='10.0.0.1/24') d1 = net.addDocker('d1', ip='10.0.0.2/24', dimage="smallko/php-apache-dev:v10") info ("create LInk\n") net.addLink(h1, d1) info("Starting Network\n") net.start() d1.cmd("/etc/init.d/ssh start") #h1.cmd(ssh -NF -L 10.0.0.1:5555:10.0.0.2:80 user@10.0.0.2") info ("Running CLI") CLI(net) info("close") net.stop if __name__ == "__main__": setLogLevel('info') topology() ``` 要確保 image 是在的 拉image 方法 ``` docker pull "image" ``` ``` root@ubuntu:/home/user/Desktop/Meowhecker# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 71288d98dc35 smallko/php-apache-dev:v10 "/bin/bash" About a minute ago Up About a minute 0.0.0.0:49158->80/tcp, :::49158->80/tcp, 0.0.0.0:49157->443/tcp, :::49157->443/tcp, 0.0.0.0:49156->9000/tcp, :::49156->9000/tcp mn.d1 ``` ``` root@d1:/# python3 -m SimpleHttpServer 80 ``` D1 Run HTTP server ``` root@d1:/# python -m SimpleHTTPServer 80 Serving HTTP on 0.0.0.0 port 80 ... 10.0.0.1 - - [19/May/2023 12:07:59] "GET / HTTP/1.1" 200 - ``` ## Local port forwarding Testing H1 request D1 ![](https://hackmd.io/_uploads/SJW4wkrrn.png) -N Do not execute a remote command. () -f Requests ssh to go to background just before command execution. (讓ssh 在背景執行) -L 本地 port (可以把他想成127.0.0.1 port) 127.0.0.1:5555 <----- SSH Turnnel --------> 10.0.0.2:80 ``` root@ubuntu:/home/user/Desktop/Meowhecker# ssh -Nf -L 5555:10.0.0.2:80 user@10. 0.0.2 ``` 連到本地HOST 5555 port ``` root@ubuntu:/home/user/Desktop/Meowhecker# curl 127.0.0.1:5555 ``` Topology2 ![](https://hackmd.io/_uploads/S1iHiIUHn.png) ```#!/usr/bin/python #!/usr/bin/python from mininet.net import Containernet from mininet.node import Docker from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.link import TCLink, Link def topology(): "Create a network with some docker containers acting as hosts." net = Containernet() info('*** Adding hosts\n') h1 = net.addHost('h1', ip='192.168.0.1/24') d1 = net.addDocker('d1', ip='192.168.0.2/24', dimage="smallko/php-apache-dev:v10") h2 = net.addHost('h2', ip='192.168.0.3/24') br1 = net.addHost('br1') info('*** Creating links\n') net.addLink(h1, br1) net.addLink(d1, br1) net.addLink(h2, br1) info('*** Starting network\n') net.start() d1.cmd("/etc/init.d/ssh start") #h2.cmd("python -m SimpleHTTPServer 8 0") br1.cmd("ifconfig br1-eth0 0") br1.cmd("ifconfig br1-eth1 0") br1.cmd("ifconfig br1-eth2 0") br1.cmd("brctl addbr br1") br1.cmd("brctl addif br1 br1-eth0") br1.cmd("brctl addif br1 br1-eth1") br1.cmd("brctl addif br1 br1-eth2") br1.cmd("ifconfig br1 up") info('*** Running CLI\n') CLI(net) info('*** Stopping network') net.stop() if __name__ == '__main__': setLogLevel('info') topology() ``` SSH Tunnel ``` root@ubuntu:/home/user/server-test/test-sshtunnel# ssh -Nf -L 4444:192.168.0.3: 80 user@192.168.0.2 -p 22 ``` (本地port):(Dst IP):(Dst port) (SSH Service) h1 Access h2 Http server ``` root@ubuntu:/home/user/server-test/test-sshtunnel# curl 127.0.0.1:4444 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html> <title>Directory listing for /</title> <body> <h2>Directory listing for /</h2> <hr> <ul> <li><a href="1.py">1.py</a> <li><a href="2.py">2.py</a> <li><a href="3.py">3.py</a> <li><a href="4.py">4.py</a> <li><a href="5.py">5.py</a> <li><a href="hello.htm">hello.htm</a> <li><a href="hi.htm">hi.htm</a> </ul> <hr> </body> </html> ``` ## Remote Port Forwarding ### Topology ![](https://hackmd.io/_uploads/HyFzdZsSn.png) --- ![](https://hackmd.io/_uploads/r1C1B_sS3.png) ``` #!/bin/bash/python3 from mininet.net import Containernet from mininet.node import Docker from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.link import TCLink, Link def topology(): "create network with container" net = Containernet() info("adding hosts") h1 = net.addHost("h1", ip="192.168.0.1/24") r1 = net.addHost("r1", ip="192.168.0.254/24") #etho 0 setting d1 = net.addDocker("d1", ip="10.0.0.1/24", dimage="smallko/php-apache-dev:v10") info("connenting each hosts") #ethID -> sequence net.addLink(h1,r1) net.addLink(r1,d1) info("start network and setting node configuration") net.start() #start d1 ssh service d1.cmd("/etc/init.d/ssh start") #Router Setting r1.cmd("ifconfig r1-eth1 0") r1.cmd("ip addr add 10.0.0.2/24 brd + dev r1-eth1") r1.cmd("echo 1 > /proc/sys/net/ipv4/if_forward") r1.cmd("iptable -t nat -A POSTROUTING -s 192.168.0.0/24 -o r1-eth1 -j MASQUERADE") h1.cmd("ip route add default via 192.168.0.254") info("running CLI") CLI(net) info("stop Network") net.stop() if __name__ == "__main__": setLogLevel('info') topology() ``` ### SNAT -o r1-eth1 # -\-out-interface D1 -> start HTTP Service ``` root@d1:/# python -m SimpleHTTPServer 80 Serving HTTP on 0.0.0.0 port 80 ... ``` ``` root@ubuntu:/home/user/Desktop/Meowhecker# python -m SimpleHTTPServer 80 & [1] 15637 ``` ### Remote port Forwarding ``` root@ubuntu:/home/user/Desktop/Meowhecker# ssh -Nf -R 10.0.0.1:5555:192.168.0.1 :80 user@10.0.0.1 -p 22 user@10.0.0.1's password: ``` 本身有 Server -> 透過 SSH tunnel 來讓外部有開 SSH Tunnel ### D1 request H1 ``` root@d1:/# netstat -tulp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 localhost:5555 0.0.0.0:* LISTEN 111/sshd: user tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN 36/sshd tcp 0 0 localhost:4444 0.0.0.0:* LISTEN 77/sshd: user tcp6 0 0 [::]:ssh [::]:* LISTEN 36/sshd ``` --- ``` root@d1:/# curl 127.0.0.1:5555 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html> <title>Directory listing for /</title> <body> <h2>Directory listing for /</h2> <hr> <ul> <li><a href="RePortFw.py">RePortFw.py</a> <li><a href="ssh2Src.py">ssh2Src.py</a> <li><a href="ssht3.py">ssht3.py</a> <li><a href="sshTunnel.py">sshTunnel.py</a> <li><a href="sshTunnel2.py">sshTunnel2.py</a> </ul> <hr> </body> </html> root@d1:/# ``` ## Topology 2 ![](https://hackmd.io/_uploads/rJzl4Jarn.png) --- ![](https://hackmd.io/_uploads/Skeqd1TB3.png) Script ``` #!/usr/bin/python from mininet.net import Containernet from mininet.node import Docker from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.link import TCLink, Link def topology(): "Create a network with some docker containers acting as hosts." net = Containernet() info('*** Adding hosts\n') h1 = net.addHost('h1', ip='192.168.0.1/24') h2 = net.addHost('h2', ip='192.168.0.2/24') br1 = net.addHost('br1') r1 = net.addHost('r1', ip='192.168.0.254/24') d1 = net.addDocker('d1', ip='10.0.0.1/24', dimage="smallko/php-apache-dev:v10") info('*** Creating links\n') net.addLink(h1, br1) net.addLink(h2, br1) net.addLink(r1, br1) net.addLink(r1, d1) info('*** Starting network\n') net.start() d1.cmd("/etc/init.d/ssh start") r1.cmd("ifconfig r1-eth1 0") r1.cmd("ip addr add 10.0.0.2/24 brd + dev r1-eth1") r1.cmd("echo 1 > /proc/sys/net/ipv4/ip_forward") r1.cmd("iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o r1-eth1 -j MASQUERADE") h1.cmd("ip route add default via 192.168.0.254") br1.cmd("ifconfig br1-eth0 0") br1.cmd("ifconfig br1-eth1 0") br1.cmd("ifconfig br1-eth2 0") br1.cmd("brctl addbr br1") br1.cmd("brctl addif br1 br1-eth0") br1.cmd("brctl addif br1 br1-eth1") br1.cmd("brctl addif br1 br1-eth2") br1.cmd("ifconfig br1 up") info('*** Running CLI\n') CLI(net) info('*** Stopping network') net.stop() if __name__ == '__main__': setLogLevel('info') topology() ``` 目標在192.168.0.1 啟動 Remote SSH Server(10.0.0.1) 開 port 做Port Forwarding 到 ### H2 Start HTTP server ``` python -m SimpleHTTPServer ``` ### H1(192.168.0.1) Establish SSH Tunnel ``` root@ubuntu:/home/user/Desktop/Meowhecker# ssh -Nf -R 10.0.0.1:4444:192.168.0.2 :80 user@10.0.0.1 -p 22 user@10.0.0.1's password: ``` ### D1(10.0.0.1) Request to inner Service curl 127.0.0.1:4444 ``` root@d1:/# curl 127.0.0.1:4444 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html> <title>Directory listing for /</title> <body> <h2>Directory listing for /</h2> <hr> <ul> <li><a href="RePortFw.py">RePortFw.py</a> <li><a href="rePortFw2.py">rePortFw2.py</a> <li><a href="ssh2Src.py">ssh2Src.py</a> <li><a href="ssht3.py">ssht3.py</a> <li><a href="sshTunnel.py">sshTunnel.py</a> <li><a href="sshTunnel2.py">sshTunnel2.py</a> </ul> <hr> </body> </html> ``` # Dynamic Port Forwarding 他跟 Local host port forwarding 有點像 只不過 Dynamic 可以改 Forward 的IP 跟 Port 會用到Proxcy 概念 ![](https://hackmd.io/_uploads/rJPzkxar2.png) --- ![](https://hackmd.io/_uploads/H1wkVlprn.png) Script ``` #!/usr/bin/python from mininet.net import Containernet from mininet.node import Docker from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.link import TCLink, Link def topology(): "Create a network with some docker containers acting as hosts." net = Containernet() info('*** Adding hosts\n') h1 = net.addHost('h1', ip='192.168.0.1/24') r1 = net.addHost('r1', ip='192.168.0.254/24') d1 = net.addDocker('d1', ip='10.0.0.1/24', dimage="smallko/php-apache-dev:v10") br1 = net.addHost('br1') h2 = net.addHost('h2', ip='10.0.0.3/24') h3 = net.addHost('h3', ip='10.0.0.4/24') info('*** Creating links\n') net.addLink(h1, r1) net.addLink(r1, br1) net.addLink(d1, br1) net.addLink(h2, br1) net.addLink(h3, br1) info('*** Starting network\n') net.start() d1.cmd("/etc/init.d/ssh start") r1.cmd("ifconfig r1-eth1 0") r1.cmd("ip addr add 10.0.0.2/24 brd + dev r1-eth1") r1.cmd("echo 1 > /proc/sys/net/ipv4/ip_forward") r1.cmd("iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o r1-eth1 -j MASQUERADE") r1.cmd("iptables -A FORWARD -s 192.168.0.1 -p tcp --dport 80 -j REJECT") h1.cmd("ip route add default via 192.168.0.254") br1.cmd("ifconfig br1-eth0 0") br1.cmd("ifconfig br1-eth1 0") br1.cmd("ifconfig br1-eth2 0") br1.cmd("ifconfig br1-eth3 0") br1.cmd("brctl addbr br1") br1.cmd("brctl addif br1 br1-eth0") br1.cmd("brctl addif br1 br1-eth1") br1.cmd("brctl addif br1 br1-eth2") br1.cmd("brctl addif br1 br1-eth3") br1.cmd("ifconfig br1 up") info('*** Running CLI\n') CLI(net) info('*** Stopping network') net.stop() if __name__ == '__main__': setLogLevel('info') topology() ``` R1 (FireWall Rules) ``` root@ubuntu:/home/user/Desktop/Meowhecker# iptables -t filter -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination REJECT tcp -- 192.168.0.1 anywhere tcp dpt:http reject-with icmp-port-unreachable Chain OUTPUT (policy ACCEPT) target prot opt source destination ``` H1 192.168.0.1 --HTTP Request--> 10.0.0.X H2 or H2 ``` root@ubuntu:/home/user/Desktop/Meowhecker# curl 10.0.0.3:80 curl: (7) Failed to connect to 10.0.0.3 port 80: Connection refused root@ubuntu:/home/user/Desktop/Meowhecker# curl 10.0.0.4:80 curl: (7) Failed to connect to 10.0.0.4 port 80: Connection refused ``` H1 做request 會被filter Table Block著 r1 firewall Rule ``` iptables -A FORWARD -s 192.168.0.1 -p tcp --dport 80 -j REJECT ``` H1 dynamic SSH tunnel ``` root@ubuntu:/home/user/Desktop/Meowhecker# ssh -Nf -D 127.0.0.1:8080 user@10.0. 0.1 -p 22 user@10.0.0.1's password: root@ubuntu:/home/user/Desktop/Meowhecker# su user user@ubuntu:~/Desktop/Meowhecker$ firefox ``` ![](https://hackmd.io/_uploads/S1QFbxar3.png) ![](https://hackmd.io/_uploads/rkT3-lTHn.png) Request 10.0.0.3:80 ![](https://hackmd.io/_uploads/ryelGxprh.png) Request 10.0.0.4:80 ![](https://hackmd.io/_uploads/S1sbzgar3.png) 如此一來就能 規避Forward 的限制去Access外部 Resource