# 設定外網以port forwarding方式連接到某個內網linux server & jupyter notebook
## 連接linux server
### 1. 安裝ssh
```=shell
$ sudo apt-get install openssh-server
```
### 2. 開啟ssh root權限 & 更改預設port
```=shell
$ sudo vim /etc/ssh/sshd_config
```
找到第13行的Port設置
```python=13
#Port 22
```
將其取消註解,更改為自定義的Port,以下為我個人的設置port使用9400。
而這個Port設定的限制會在會後面port forwarding的時候說明。
```python=13
Port 9400
```
再找到第32行ssh root權限的設置,只要確認是註解的狀態即可。
```python=13
#PermitRootLogin prohibit-password
```
### 3. 確認虛擬IP位置
```=shell
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.94 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::205:6bff:fe01:a419 prefixlen 64 scopeid 0x20<link>
ether 00:05:6b:01:a4:19 txqueuelen 1000 (Ethernet)
RX packets 129812 bytes 9482698 (9.4 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11420 bytes 11799912 (11.7 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 29 base 0xb000
```
:::info
上面eth0為我server主機上的Ethernet網卡,
每台主機所連到網際網路的網卡代稱可能不一定是eth0,
也有可能是無線網卡,自己注意。
:::
此時可以看到我的linux server的IP是```192.168.1.94```
該IP為虛擬IP,是由路由器(Router)藉由某個固定IP分配出來的一個虛擬IP。
請記住這裡的IP ```address```與```netmask```數值
### 4. 設定固定ip (static ip)
:::warning
若網路設定並非DHCP,請跳過此步驟到下一步。
:::
```=shell
$ sudo vim /etc/network/interfaces
```
```python=1
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
```
針對你的網卡(以我為例就是```eth0```)將```dhcp```修改為固定IP(```static```)
:::danger
必須確認此IP沒有其他人使用。
且必須在路由器設置中將此IP保留(此設定請參照各家路由器之說明書)。
:::
```python=1
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.1.94
netmask 255.255.255.0
gateway 192.168.1.1
```
此處```address```, ```netmask```與3.相同
```gateway```就要依據各個路由器所設置之不同
但大部分如果是```192.168.1.xxx```預設是```192.168.1.1```
```192.168.0.xxx```預設是```192.168.0.1```這樣子
再重新開啟網路設定即可
```=shell
$ sudo /etc/init.d/networking restart
```
### 5. 設置port forwarding

先大致介紹一下port forwarding的概念
假設今天我要從電腦A透過ssh連到電腦E
若今天我下指令
```
$ ssh <username>@192.168.1.94
```
結果會發現,
竟然連到了電腦C(如果電腦C也有一樣的username啦:stuck_out_tongue_winking_eye:)
原因是因為我們所用的```192.168.1.94```是屬於Router A下的虛擬IP,
所以電腦A使用```192.168.1.94```只能找到的是同一個Router A下的電腦C而非Router B下電腦E。
那這個時候該怎麼辦?
即便使用```140.yyy.yyy.yyy```也不能確定能連到電腦D、電腦E還是電腦F。
這時候就要用到```Port```(連接阜)的概念啦。

如上圖,
假設Router B的```port 9400```設定為轉接給電腦E的```port 9400```,
那當你從電腦A要連接到電腦E的時候就可以透過固定IP加上port forwarding的方式轉接到電腦E:
```
$ ssh <username>@140.yyy.yyy.yyy -port 9400
```
就能順利連接到電腦E而非電腦C,
而port forwarding的設定請參照各家路由器之說明書。
:::info
大致的設定概念(上述圖例,針對Router B):
原始IP位址:```140.yyy.yyy.yyy```
對應IP位址:```192.168.1.94```
原始Port:```9400```
對應Port:```9400```
:::
:::danger
1.設置port時,數值範圍```1024-65535```,請跳過```0-1023```(重要protocol已佔用)與已被其他人在此server佔用的port,也請不要用預設的```ssh port 22```。
2.原始Port、對應Port可以不同。
:::
## 連接jupyter notebook
### 1. 安裝jupyter
#### python3版本
```=shell
$ pip3 install --upgrade pip
$ pip3 install jupyter
```
#### python2版本
```=shell
$ pip install --upgrade pip
$ pip install jupyter
```
### 2. 新增configuration檔案並修改
#### 回到```/home/<username>```
```=shell
$ cd ~/home/<username>
```
#### 產生configuration檔
```=shell
$ jupyter notebook --generate-config
```
#### 設置```jupyter notebook```密碼
```=shell
$ jupyter notebook password
Enter password: ****
Verify password: ****
[NotebookPasswordApp] Wrote hashed password to /Users/you/.jupyter/jupyter_notebook_config.json
```
產生的configuration檔會在```./jupyter/jupyter_notebook_config.py```
#### 修改configuration檔成以下
```=shell
$ vim ./jupyter/jupyter_notebook_config.py
```
允許```jupyter notebook```使用root權限
```python=62
c.NotebookApp.allow_root = True
```
開放所有IP可以連接
```python=204
c.NotebookApp.ip = '*'
```
啟動```jupyter notebook```時,
本地端(localhost,也就是server端)不打開browser(網頁瀏覽器)。
```python=272
c.NotebookApp.open_browser = False
```
```jupyter notebook```使用port forwarding時所使用的port
```python=292
c.NotebookApp.port = 9450
```
### 3. 設置port forwarding
接續如5.所述之設定

```Port 9400```已被```ssh```所佔據,所以另外再打開```Port 9450```供```jupyter notebook```port forwarding使用。
一樣port forwarding的設定請參照各家路由器之說明書。
:::info
大致的設定概念(上述圖例,針對Router B):
原始IP位址:```140.yyy.yyy.yyy```
對應IP位址:```192.168.1.94```
原始Port:```9450```
對應Port:```9450```
:::
:::danger
1.設置port時,數值範圍```1024-65535```,請跳過```0-1023```(重要protocol已佔用)與已被其他人在此server佔用的port,也請不要用預設的```ssh port 22```。
2.原始Port、對應Port可以不同。
:::
### 4. 在client端連接server端的```jupyter notebook```
在server端(電腦E)的```terminal```輸入
```=shell
$ jupyter notebook
```
在client端(電腦A)打開browser(網頁瀏覽器)
在網址處輸入```140.yyy.yyy.yyy:9450```
再輸入密碼就可以在client端使用server端的```jupyter notebook```囉!
### 5. su 權限
在4.的步驟中將
```=shell
$ jupyter notebook
```
改成
```=shell
$ sudo jupyter notebook --no-browser --allow-root --port 9450
```