> 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).

# 遠端登入執行程式

當只有一個 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 來停止這些程式。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://openwrt-nctu.gitbook.io/project/openwrt-compile-env/openwrt-remotely-control.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
