> For the complete documentation index, see [llms.txt](https://openwrt-nctu.gitbook.io/project/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://openwrt-nctu.gitbook.io/project/openwrt-compile-env/openwrt-remotely-control.md).

# 遠端登入執行程式

透過 rsa 金鑰, nohup, 來操作多個 OpenWRT AP

當只有一個 OpenWRT AP 的時候，我們可以透過 SSH 登入，進行操作。但是，當我們有一整群 OpenWRT AP 時，在這些 AP 上執行程式，就變得一件麻煩的事情。

為了避免不斷登入的麻煩，我們需要兩個工具: 首先是要有免用密碼登入 OpenWRT 的手段，第二，則是要能夠遠端執行並終止程式。

## 以金鑰方式登入 OpenWRT

對於 Linux 系統而言，有兩種登入的方式。第一種是透過密碼方式，也就是傳統的登入方式。第二種則是透過金鑰方式登入，此方式由於不需要密碼，故可以用 script 的方式交換資訊。

為了要以金鑰方式登入，首先，要先擁有金鑰 (key)，在 Linux 系統中，我們可以用以下指令產生金鑰對:

```
 ssh-keygen -t rsa -P ""
```

此指令會產生一組無密碼保護的金鑰對 (id\_rsa、id\_rsa.pub) 在 `.ssh` 的目錄底下。接著我們要把這組金鑰設定為登入的金鑰，也就是把 id\_rsa.pub 設定成登入的金鑰，指令如下:

```
cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys
```

接著，安裝 openssh 的 server 和 client:

```
sudo apt-get install openssh-server openssh-client
```

完成後，我們可以先 SSH 本機，看看設定是否正確。

```
$ssh localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is d1:f5:35:ae:1a:2e:69:e4:4d:b4:5e:2d:02:a4:f2:ed.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
```

當第一次登入時，會出現 `ECDSA key fingerprint is ...` 這樣的訊息，輸入確認，下一次再登入時就不會出現了。

接著，假設 OpenWRT 的 IP 位址為 192.168.1.1，可以透過以下指令來設定為使用金鑰登入。相同的，第一次會出現認證資訊，確認之後就可以無密碼登入。

```
scp ~/.ssh/authorized_keys root@192.168.1.1:/etc/dropbear/
```

{% hint style="info" %}
OpenWRT 官網上有許多資源，例如這裡的設定就是參考: <https://openwrt.org/docs/guide-user/security/dropbear.public-key.auth>
{% endhint %}

## 背景執行程式以及透過指令停止程式

在 Linux 環境執行程式時，當我們關閉遠端的 SSH 視窗時，也就會停止程式的執行，這是因為關閉視窗等效於停止一個 session，而此終止 session 的動作會發一個信號 (hangup) 給所有在此 session 下執行的程式，邀邱他們停止。

為了避免這一件事情，我們可以使用 nohup (no hangup) 的指令來執行程式，此時，由於沒有中斷信號，程式就可以在背景執行。通常來說，指令可以表示如下:

```
nohup /path/my_program &
```

最後的 `&` 代表背景執行，因此不會顯示任何資訊於視窗中。

在 OpenWRT 中，nohup 並不是一個內建的指令，因此，在使用前要先安裝此指令:

```
opkg install coreutils-nohup
```

{% hint style="info" %}
這部分的架構又稱為 Linux Daemon (守護進程)，與 Linux的系統設計相關，可以參考:

<http://linux.vbird.org/linux_basic/0560daemons.php>
{% endhint %}

當我們可以透過 `nohup` 執行程式之後，下一個問題就變成要如何結束程式。在 Linux 系統中，每一隻程式都會有一個 ID (PID)，在一般的系統下，可以透過 `ps` 這個指令來查詢目前執行程式的 PID。但是很明顯的，此方法費工又沒效率，因此，我們修改一下 `nohup` 的指令，記錄下執行程式的 PID。

```
nohup /path/my_program > logfile.txt & echo $! > pidfile.txt &
```

此指令將會把原本程式輸出的結果寫入 logfile.txt 中，並把 PID 的資訊(透過 `$!` 取得)寫入 pidfile.txt 中，因此，當我們想要關閉剛剛透過 `nohup` 執行的程式時，就只需要輸入:

```
kill -9 'cat pidfile.txt'
```

透過以上兩個方法，並搭配上面無密碼登入的教學，就可以寫一隻 shell script 來開啟多台 OpenWRT AP 上的程式，並在寫另一隻 shell script 來停止這些程式。
