# Mininet-containernet 3 /SSH tunnel
[TOC]
Topology

```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

-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

```#!/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

---

```
#!/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

---

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 概念

---

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
```


Request 10.0.0.3:80

Request 10.0.0.4:80

如此一來就能 規避Forward 的限制去Access外部 Resource