テレワークが一般的に普及してきた昨今、IPAが提供しているシン・テレワークシステムを使用する場面もあると思います。
最低限の設備投資でエンタープライズ環境用ポリシー規制サーバーを構築してみます
https://telework.cyber.ipa.go.jp/enterprise/
サーバーソフトウェアの作成
最低限の構成としたいので一つのファイルで完結するGO言語で作成する。
ファイルを一つ配信するだけなのでNginxで直接ファイル配信するのもアリ。
その場合は読み飛ばしてください
証明書の作成
ポリシーサーバーはhttpsが必須で、なんでもいいのでTLS1.2かTLS1.3が必須とのこと
ポリシーサーバーには、TLS 1.2 または TLS 1.3 で、何らかの SSL 証明書 (RSA X.509 1024bit ~ 4096bit のいずれか) が設定されている必要があります。
opensslでセルフ証明書を作成する
$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 365 -req -sha256 -signkey server.key < server.csr > server.crt
使用する成果物はserver.key
とserver.crt
の二つ
ポリシーの作成
サンプルを参照する。
どうも本文内に空行が存在すると無効になるらしいので必要な部分だけ抜き取ってpolicy.txt
というファイルを作成する。
今回はひとまずメッセージとsyslogの設定のみ
SERVER_MESSAGE コンピュータID・パスワード・ファイルの取り扱いには十分に注意してください<BR>万が一疑わしい事態が発生した場合や不明点は担当(****)まで
SYSLOG_HOSTNAME xxx.xxx.xxx.xxx
SYSLOG_PORT 514
クライアントソフト
GO言語で作成
goのバージョンは1.19.7
で作成。
もう少し低いバージョンでもいいが、TLS1.3のサポートが1.17
くらいだったはず
このファイルと同一ディレクトリに上で作ったpolicy.txt
とserver.key
とpolicy.crt
を配置する
アレンジはお好みでどうぞ
package main
import (
"crypto/tls"
"log"
"net/http"
"os"
"strings"
_ "embed"
"github.com/go-chi/chi/v5/middleware"
)
// ポリシーファイル。以下のサンプルを編集して同一policy.txtという名前で保存する
// https://telework.cyber.ipa.go.jp/enterprise/sample_policy.txt
//
//go:embed policy.txt
var policy []byte
// 作成したサーバー秘密鍵
// 1024bit ~ 4096bit
// TLSを使用しないなら空ファイルで良い
//
//go:embed server.key
var private []byte
// 作成したサーバー証明書
// 期限が切れていてもよい
// TLSを使用しないなら空ファイルで良い
//
//go:embed server.crt
var cert []byte
// 待ち受けするアドレス
var addr string = "10.255.255.127:443"
func init() {
// 起動時に環境変数"ADDR"を読み込んで待受アドレスを変更する
a := os.Getenv("ADDR")
if len(a) > 0 {
addr = a
}
}
// 最低限のhttpハンドラ
func handle(w http.ResponseWriter, r *http.Request) {
if strings.TrimRight(r.URL.Path, "/") == "/get-telework-policy" {
w.Write(policy)
return
}
w.WriteHeader(http.StatusNotFound)
}
// net/httpに渡すハンドラ
// 機能を増やすならここでchiなりginなりを使用するとよい
func newHandler() http.Handler {
var handler http.Handler
handler = http.HandlerFunc(handle)
// ログを表示したいのでgo-chiのものを使用する
handler = middleware.Logger(handler)
return handler
}
// TLSを使用しない
func run() error {
return http.ListenAndServe(addr, newHandler())
}
// TLSを使用して開始
func runTLS() error {
keyPair, err := tls.X509KeyPair(cert, private)
if err != nil {
return err
}
srv := &http.Server{
Addr: addr,
Handler: newHandler(),
TLSConfig: &tls.Config{
ServerName: "10.255.255.127",
Certificates: []tls.Certificate{keyPair},
CipherSuites: []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
},
PreferServerCipherSuites: true,
MinVersion: tls.VersionTLS12,
MaxVersion: tls.VersionTLS13,
},
}
return srv.ListenAndServeTLS("", "")
}
func main() {
var err error
err = runTLS()
if err != nil {
log.Fatal(err)
}
}
依存パッケージの取得
$ go get github.com/go-chi/chi/v5/middleware
アプリの動作確認
$ ADDR=:8080 go run main.go
もう一つターミナルを起動してcurlを打ってみる
$ curl https://localhost:8080/get-telework-policy/
curl: (60) SSL certificate problem: self-signed certificate
More details here: https://curl.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
いわゆるオレオレ証明書なのでこんなエラーになる。
では--insecure
オプションをつけて証明書の検証をスキップさせて再度検証
$ curl --insecure https://localhost:8080/get-telework-policy/
SERVER_MESSAGE パスワード・コンピュータID・ファイルの取り扱いには十分に注意してください<BR>万が一疑わしい事態が発生した場合や不明点は担当(****)まで
SYSLOG_HOSTNAME xxx.xxx.xxx.xxx
SYSLOG_PORT 514%
意図通りのポリシーが返ってきたら完了
ビルド
ビルドして一つの実行ファイルに固める。
今回はRaspberry Pi上で動かすのでarm向けにコンパイル
$ GOOS=linux GOARCH=arm go build main.go
何もエラーがなかったらmain
というファイルが作成されていると思います
ルーターの設定
ドキュメントによるとテレワークシステムは定期的に10.255.255.127
へのアクセスを試みるという。
というわけでルーターに静的ルーティングを追加し、上記ip宛のパケットを任意のアドレスにルーティングさせる
まず配信サーバーとして動作させるRaspberryPiのIPを固定する。
そしてルーターのルートテーブルを変更する。
例えば、RaspberryPiの固定IPが192.168.0.100
として、
ヤマハのルーターならこう
ip route 10.255.255.127 gateway 192.168.0.100
RaspberryPiの設定
いよいよRaspberryPi側の設定。
ネットワーク設定(RaspberryPi側)
この時点で10.255.255.127
宛のパケットはRaspberryPiに飛んでいるはず。
RaspberryPiにそのアドレスを認識させて、パケットを受け取るようにする。
$ sudo ip address del 10.255.255.127 dev eth0
WiFi接続している場合はeth0
の部分を変更する。
pingを飛ばして受け取っているかを確認。
windowsでコマンドプロンプトを起動し、下記コマンドを打つ
>ping 10.255.255.127
10.255.255.127 に ping を送信しています 32 バイトのデータ:
10.255.255.127 からの応答: バイト数 =32 時間 =1ms TTL=64
10.255.255.127 からの応答: バイト数 =32 時間 <1ms TTL=64
10.255.255.127 からの応答: バイト数 =32 時間 <1ms TTL=64
10.255.255.127 からの応答: バイト数 =32 時間 <1ms TTL=64
10.255.255.127 の ping 統計:
パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 0ms、最大 = 1ms、平均 = 0ms
サーバーを動作
上で作ったmain
をRaspberryPiに転送して動かしてみる。
$ sudo ./main
そしてwindowsのブラウザから下記URLにアクセスする。
https://10.255.255.127/get-telework-policy/
この接続ではプライバシーが保護されません みたいな警告が出たら成功。
詳細設定
をクリックして10.255.255.127にアクセスする(安全ではありません)
をクリックしてみましょう
このタイミングでシン・テレワークサーバー設定を起動すればこんな表示が出ると思います
(確認間隔の影響で最大5分のタイムラグがあるかも)
これが意図通りだったら疎通確認は完了です。
常駐化
これを常駐化させて再起動しても動くようにしましょう。
アドレス追加の自動化
ip addr add
は終了するとリセットされるのでsystemdに登録して起動時にコマンドを打たせる
$ sudo vim /etc/systemd/system/add-address.service
Description = add virtual address
After = syslog.target
[Service]
ExecStart = /usr/sbin/ip address add 10.255.255.127 dev eth0
Type = oneshot
RemainAfterExit=yes
[Install]
WantedBy = multi-user.target
そして有効化
$ sudo systemctl enable /etc/systemd/system/add-address.service
※本当は[Install]の部分を適切に設定したほうがいいが今回は割愛
アプリケーションのdaemon化
まずmain
を専用ディレクトリに格納する。場所はお好みで
$ sudo mkdir /opt/thin-telework
$ sudo mv main /opt/thin-telework/
サービスファイルを作成する
$ sudo vim /etc/systemd/system/thin-telework.service
Description = thin telework policy server
After = syslog.target
[Service]
WorkingDirectory = /opt/thin-telework
ExecStart = /opt/thin-telework/main
Restart=on-success
Type = simple
StandardError = syslog
NotifyAccess = all
[Install]
WantedBy = multi-user.target
作成したら有効化して起動
$ sudo systemctl enable thin-telework.service
Created symlink /etc/systemd/system/multi-user.target.wants/thin-telework.service → /etc/systemd/system/thin-telework.service.
$ sudo systemctl start thin-telework.service
$ sudo systemctl status thin-telework.service
● thin-telework.service
Loaded: loaded (/etc/systemd/system/thin-telework.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-10-23 08:37:32 BST; 37min ago
Main PID: 852 (main)
Tasks: 4 (limit: 877)
CGroup: /system.slice/thin-telework.service
└─852 /opt/thin-telework/main
動作確認
RaspberryPiとWindowsを再起動し、テレワークシステム設定画面で設定が反映されていれば完了