Raspberry Pi OSにてNATやる備忘録
動機
RasPi4にArch Linux for ARM入れてNAT組んでとかやっていたが,アップデートかませてから動かなくなった.おそらくSDカードの寿命.
せっかくなのでRaspberry Pi純正OSのRaspberry Pi OSにて同様の動作をする環境を作りたかった.
目標の構成としてはNATの上流側がWi-Fi環境であり下流が優先LANである.
逆に設定するのが通常であると考えられるが,私は家のDHCPによるIP自動払い出しのWi-Fiにしか接続できない環境にあり,一方で自室内に自分専用のネットワークを組みたいという欲望からこのようなことが必要になる.
作業環境
既に有線回線側の接続予定のローカルネットワークは組まれていてその中には外部との接続を可能にするためのNATが組まれたPCがあり,DHCPサーバよりルーティングも可能になっている状況にある.
すなわち今回の作業で得たい環境はすでに別機器によって再現されている環境にある.
SDカードへのRaspberry Pi OSのインストール
Raspberry Pi Imagerを用いてRaspberry Pi OS Lite(64bit)をSDカードに焼きこむ.
この際ssh設定とユーザー名&パスワード設定を必ずチェックボックスを入れて設定する.
Raspberry Piの起動
SDカードをRaspberry Piに差し込み,有線LANを接続する.Raspberry PiにはPoE hatが接続されており,接続先のスイッチもPoE出力のある物なので自動的に起動する.
DHCPの払い出しにより自動的にIPアドレスが割り振られ,sshで接続できるようになっているはずである.sshでRaspberry Piに接続する.
systemd-networkd
まず有線側を固定IPとして設定する.
$ sudo vim /etc/systemd/network/20-wired.network
[Match]
Name=eth0
[Network]
Address=10.0.2.5
[DHCPv4]
RouteMetric=20
次に無線側をDHCPとして設定する.
$ sudo vim /etc/systemd/network/25-wireless.network
[Match]
Name=wlan0
[Network]
DHCP=yes
IgnoreCarrierLoss=3s
[DHCPv4]
RouteMetric=10
systemd-networkdの自動起動とdhcpcdの自動起動停止
$ sudo systemctl disable dhcpcd
$ sudo systemctl enable systemd-networkd
再起動
$ sudo reboot
ここまでできていれば再起動後も同様にssh接続できるはず.
再度ssh接続した後,ルーティングは自動的に設定されないため
$ sudo ip route add default via $ROUTING_ADDR dev eth0
ここで$ROUTING_ADDRはデフォゲのアドレス.一時的なもの.
Wi-Fi側の接続
iwdを用いる
$ sudo apt install iwd
$ sudo systemctl disable wpa_supplicant.service
$ rfkill unblock wifi
$ reboot
$ sudo systemctl start iwd
$ sudo systemctl enable iwd
$ sudo iwctl
[iwd] station wlan0 connect SSID
ここでWi-Fiパスワードをうち,その後quitでiwdの対話から抜ければWi-Fi側(今回の場合は上流)にも接続できる.
ipフォワーディング
$ sudo vim /etc/sysctl.d/30-ipforward.conf
net.ipv4.ip_forward=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1
iptablesによるNAT関係
$ sudo apt install iptables
$ sudo apt install iptables-persistent
$ sudo systemctl enable iptables
$ sudo systemctl start iptables
$ sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/255.255.255.0 -o wlan0 -j MASQUERADE
$ sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$ sudo iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT
$ vim test.sh
#!/bin/bash
iptables-save > /etc/iptables/rules.v4
$ sudo chmod a+x test.sh
$ bash ./test.sh
$ sudo reboot
DHCPサーバ
$ sudo apt install sci-dhcp-server
DHCPサーバの設定
設定内容は割愛
同一LAN内で動作しているdhcpサーバを落として
$ sudo systemctl enable sci-dhcp-server
$ sudo systemctl start sci-dhcp-server
今回の学び
iptablesの設定ファイルはArch Linuxでは/etc/iptables/iptables.rulesであるが,Raspberry Pi OSでは/etc/iptables/rules.v4となる.
また,aptではiptablesのみでは動かない,iptables-persistentも同時に入れる.
pacman上でのパッケージdhcpdはapt上ではisc-dhcp-server,同様にsystemdにて起動するサービスもisc-dhcp-server.service
Arch Linuxにてiwdを用いたEduroam Wi-Fiへの接続(慶應以外も使えるかも.keiomobile2へも転用可能)
背景
初めてArch Linuxを物理マシンにインストールした頃のブートディスクはnetctlでWi-Fiに繋いだ.当時はそれに倣ってnetctlを使用していたが,久しぶりにArch Linuxのインストール作業を行ったところ,ブートディスクに入っている無線関係がiwdに入れ替わっていた.せっかくなので大学へ持っていっているラップトップもiwdに入れ替えたらkeiomobile2だのeduroamだのの設定で詰まったので備忘録
実行
書いたスクリプトはここに置いてきた.
https://github.com/Hebereke555/eduroam-iwd
iwdでのeduroamの設定ファイルは " /var/lib/iwd/eduroam.8021x " となる.
中身は
[Security]
EAP-Method=PEAP
EAP-Identity=YOUR@ID
EAP-PEAP-CACert=/etc/ssl/certs/Security_Communication_RootCA2.pem
EAP-PEAP-Phase2-Method=MSCHAPV2
EAP-PEAP-Phase2-Identity=YOUR@ID
EAP-PEAP-Phase2-Password=YOURPASS
[Settings]
AutoConnect=True
となる.ここでIDは大学のID(弊学であればsomeone@keio.jp),Passwordは各大学のサービスへのログインパスではなく,Wi-Fi用にパスワードがあるはずなので探す.
CA証明書に関しては大学によって違う可能性あり.iwdでのeduroamに接続に関する質問スレッドにて登場していた証明書は異なるものであったため.
このファイルを生成するためのシェルスクリプトをGitHubに置いてきた.実行すれば設定ファイルを生成できるはず.ただし/var/lib/iwd/に書き込むため,sudoersである必要がある.
keiomobile2についてはファイル名をkeiomobile2.8021xにしてやればよい.
iwdの再起動
$ sudo systemctl restart iwd
たぶん再起動しなくてもiwdが有効になっていれば勝手につながる.私は基本大学以外でWi-Fiつかわないので.
Ubuntu Server 20.04 LTSにRocket.Chatを入れる(ただの備忘録,不正確な可能性あり)MyDNS.jpの無料ドメインでLet's Encrypt
参考にしたページ
https://qiita.com/bibimarujp/items/b1bebba9dd67422031c6
https://docs.rocket.chat/installing-and-updating/manual-installation/configuring-ssl-reverse-proxy
https://docs.rocket.chat/installing-and-updating/manual-installation/ubuntu
https://www.mydns.jp/members/#domaininfo
UbuntuとRocket.Chatのインストール
Proxmox上にUbuntu server 20.04 LTSをインストールし,そこにRocket.Chatを入れていく.Ubuntu Serverのインストールディスクを選択して起動,ある程度設定決めたところで「なにかサードパーティソフト入れる?」的な選択肢が出てくる.その中にRocket.Chatがあるのでチェック入れてインストールする(その画像に関しては上記参考ページのqiitaのものを参考にしてください).
すでに動いているUbuntu Server の場合は公式のインストール方法みるのが正解.
Rocket.Chatの初期設定
LAN内で作業.作業端末のブラウザでRocket.Chatの鯖の3000番ポートにアクセス.
初期設定をやる.このへん参照.プライベート用途だった場合「登録」項目はしっかり弄った方がいい.
https://www.itcore.jp/tips/rocketchat.php
Let's Escrypt
まず,ドメインが必要.私は動的グローバルIPの回線しか持っていないのでDynamic DNSに登録する必要がある.今回はMyDNS.jpさんを利用させていただいた.
Let's Escryptでの証明書発行についてGitHubに公開されていて非常にやりやすい.
無料ドメインの枠を使わせていただいた.ここでは????????.&&&&&&.mydns.jpとする.
ポートフォワーディングに関しては自分でやって.この時点で外から見たときの80番と443番は開いとく.
Ubuntu Serverにて
# apt install nginx certbot python3-certbot-nginx php php-mbstring unzip vim
# systemctl start nginx
もしnginxが立ち上がらなかったらたぶんApacheが邪魔してる.Ubuntuのインストールすると初期設定で自動起動有効なのほんと嫌い.私の環境ではいつ紛れ込んだのか分からないけれどもApacheが入ってて設定途中に再起動したらApache立ち上がってNginx立ち上がらなくなってた.
# systemctl disable apache2.service
# systemctl stop apache2.service
# mkdir /root/SSL
# cd /root/SSL
# wget 'https://github.com/disco-v8/DirectEdit/archive/master.zip' -O DirectEdit-master.zip
# unzip DirectEdit-master.zip
# cd DirectEdit-master
# chmod 700 ./*.php
# chmod 600 ./*.conf
# vim txtedit.conf
$MYDNSJP_MASTERID = 'yourmasterid';
$MYDNSJP_MASTERPWD = 'yourpasswd';
$MYDNSJP_DOMAIN = '????????.&&&&&&.mydns.jp';
# sudo certbot certonly --manual --preferred-challenges=dns --manual-auth-hook /root/SSL/DirectEdit-master/txtregist.php --manual-cleanup-hook /root/SSL/DirectEdit-master/txtdelete.php -d ????????.&&&&&&.mydns.jp --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -m your@mailaddress --manual-public-ip-logging-ok
もしかしたらこのコマンド前にnginx一回立ち上げとかなきゃかも.その場合
# systemctl start nginx
出来た公開鍵は/etc/letsencrypt/live/????????.&&&&&&.mydns.jp/fullchain.pem
秘密鍵は/etc/letsencrypt/live/????????.&&&&&&.mydns.jp/privkey.pem
# vim /etc/nginx/sites-enabled/default
Upstreams
upstream backend {
server 127.0.0.1:3000;
}
# HTTPS Server
server {
listen 443;
server_name ????????.&&&&&&.mydns.jp;
# You can increase the limit if your need to.
client_max_body_size 200M;
error_log /var/log/nginx/rocketchat.access.log;
ssl on;
ssl_certificate /etc/letsencrypt/live/????????.&&&&&&.mydns.jp/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/????????.&&&&&&.mydns.jp/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # don’t use SSLv3 ref: POODLE
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
書き終わったら
# systemctl restart nginx
自動起動にするために
# systemctl enable nginx
おそらくこれで "別回線" から????????.&&&&&&.mydns.jpにアクセスすればhttpsでRocketChatにアクセスできる.オレオレ証明ではないのでAndroidアプリからもアクセス可能となる.
今回の教訓 Ubuntuはなんでもかんでも勝手に立ち上げる.殺せ.
Proxmox VE上のVMから実ディスクにアクセスする(ディスクパススルー)
参考にしたページ
https://kiyoka.moe/2020/08/04/proxmox-ve-hdd-attach-with-kvm/
背景
ラックマウントサーバを入手してとりあえずはArch Linuxを入れて遊んでいたがリソース余りまくりなのでProxmox VEを入れて色々試そうと思った.OSに認識されるディスクは/dev化にsda,sdb,sdcと3つある状態であった.必要な情報をsdaからsdbに移し,sdaにProxmox VEを入れ,その中にArch LinuxのVM(VMidは100)を立てた.今回の目的はこのArch LinuxのVMから直接sdb内に触れるようにすること.また,今回使用したDiskはSAS規格のものである.
ハードウェアパススルーではない.
設定
proxmox自体のシェルを ' pve # ' で,proxmox上の仮想マシン(今回はArch Linux)のシェルを ' vm # ' とする.
pve # ls /dev/disk/by-id
ata-hp_DVDROM_略
dm-name-pve-root
dm-uuid-LVM-略
lvm-pv-uuid-略
lvm-pv-uuid-略
scsi-3609999c2222c0aaaaaaaaaaaaaaaaaa
scsi-3609999c2222c0aaaaaaaaaaaaaaaaaa-part1
scsi-3609999c2222c0bbbbbbbbbbbbbbbbbb
scsi-3609999c2222c0bbbbbbbbbbbbbbbbbb-part1
scsi-3609999c2222c0dddddddddddddddddd
scsi-3609999c2222c0dddddddddddddddddd-part1
scsi-3609999c2222c0dddddddddddddddddd-part2
scsi-3609999c2222c0dddddddddddddddddd-part3
scsi-3609999c2222c0dddddddddddddddddd-part4
以下略
今回はSAS規格のHDDなのでscsiから始まるものがHDDである.SATAのHDDを使っている場合ataから始まる.part1等となっているのはディスクのパーティションである.そのためディスクそのものは無印のものである.part4まであるものはProxmoxのインストールディスクである(おそらく普通はpart3まで.個人的用途で4つにパーティションを区切っている).
今回scsi-3609999c2222c0aaaaaaaaaaaaaaaaaaをVMにマウントすることにする.
pve # cat /etc/pve/nodes/servername/qemu-server/100.conf|grep scsi
scsi0: Drive1:vm-100-disk-0,size=45G
scsi0は予約されているため
pve # qm set 100 -scsi1 /dev/disk/by-id/scsi-3609999c2222c0aaaaaaaaaaaaaaaaaa
構文としては
pve # qm set VMid -scsiX DiskNum
再度
pve # cat /etc/pve/nodes/servername/qemu-server/100.conf|grep scsi
を実行するとscsiが追加されているのが分かる.
あとはVMを再起動(おそらくrebootコマンドではなく一旦shutdownしてからProxmox VEのWeb管理画面で再度電源を入れないとダメ)してから
vm # ls /dev
でsdbやsdb1が表示されればOK
Windows等でうまくいくかは知らない
以上
同一LAN内に二つのルータをもつ場合におけるデフォゲ以外からのsshアクセス・ポリシーベースルーティング(PBR)
背景
大学院に進学したため,現状未だ親元を離れずにいる.家の回線速度に文句は無いが,回線の管理は親が行っているためポート開放が出来ない.また固定IPにもできないため,まず親の管理するLANの下に自分で管理するLANを作った.さらに外部からのアクセスを可能にするために一つ回線を契約した.親の家であり,新しく有線を引くことは不可能であったため,グローバルIPが割り振られるSIMカードを契約,それをSIMカード対応のルータに入れて自分のLANに接続した.
ポートフォワードできる自分の回線はモバイル回線であり大容量は使えないため,ssh鯖への外部(WAN)からのアクセス以外は実家の回線を使いたい.故にssh鯖のデフォゲはMyRouterの192.168.10.1/24となっている.しかしこのままでは外部からLTE Routerを経由してアクセスした際にその応答がMyRouterに流れてしまい,非対称ルーティングとなってしまう.クライアント側で対処する方法として非対称ルーティングを許可することも出来る(はず)だが,セキュリティ的に望ましくないので鯖側でPort由来のPolicy Based Routing(PBR)を設定する.
LTE Routerでのポートフォワーディングは設定済み,ssh鯖のPortは22.鯖の設定は全てrootユーザで行う.
参考にしたページ
https://qiita.com/MT-07/items/fa7f34a5dec34b6a0757
作業
iptablesで特定ポートのパケットに印1をつける
# iptables -t mangle -A OUTPUT -p tcp --sport 22 -j MARK --set-mark 1
sportとdportを間違えて2日ほど悩んだ.素人かよ
https://oshiete.goo.ne.jp/qa/7126780.html
iproute2で印のついたパケットに適用するルーティングテーブルを設定する.
# ip rule add fwmark 1 table 10
iproute2でtable10のルーティング設定を行う.
# ip route add default dev eth0 via 192.168.10.100 table 10
このままだとLAN内からアクセスする際に応答が帰ってこなくなるので
LAN内に関するルーティングを追記する.
まず ip routeを実行し
# ip route
default via 192.168.10.1 dev eth0
192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.22
上記の様に出力されたら
# ip route add table 10 192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.22
複数行であったらdefault以外全てについて同様に行う.
自動化
iptablesについては
# iptables-save > /etc/iptables/iptables.rules
# systemctl enable iptables
iproute2については
# cat /root/Shells/pbr.sh
#!/bin/bash
ip rule add fwmark 1 table 10
ip route add default dev eth0 via 192.168.10.100 table 10
ip route add table 10 192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.22
# cat /etc/systemd/system/pbr.service
[Unit]
Description=start PBR
After=netctl@eth0.service
[Service]
ExecStart=/root/Shells/pbr.sh
Type=idle
[Install]
WantedBy=multi-user.target
# systemctl enable pbr.service
以上
Arch LinuxでLACPを試す ついでにRAMDiskも
友人からマザボをもらった.LANポートが2つついていた.(ありがとう,有効に使ってる)
別の友人からそそのかされた.UniFiのスイッチを買ってコントローラを譲ってもらった.(相談乗ってくれてありがとう)
なので今回はLACPやってみる.リンクアグリゲーションやってみたかっただけ
スイッチ側はCloudKeyにアクセスしてGUIで設定するだけなので割愛.
Arch Linux側の設定の備忘録.
参考ページ
https://wiki.polaire.nl/doku.php?id=archlinux_bonding
https://wiki.archlinux.jp/index.php/Netctl#.E3.83.9C.E3.83.B3.E3.83.87.E3.82.A3.E3.83.B3.E3.82.B0
設定
作業はローカルアクセスでやる.
LANを片方のみ繋いでおいて
$ sudo pacman -S netctl ifenslave
次のコマンドでインターフェース名を調べてメモる
$ ip link
$ sudo vim /etc/netctl/bonding
以下ファイル内------------------------------------------------------------------------------------------
Interface='bond0'
Connection=bond
BindsToInterfaces=('eth0' 'eth1')
IP=dhcp
IP6=stateless
以上---------------------------------------------------------------------------------------------------------
とりあえずdhcpで繋ぐ.DHCPサーバでMACアドレスを元に固定するため
固定IPを直接書く人はArch Wikiあたり見て
$ sudo vim /etc/modprobe.d/bonding.conf
以下ファイル内------------------------------------------------------------------------------------------
options bonding mode=802.3ad miimon=100
以上---------------------------------------------------------------------------------------------------------
もともとdhcpcdでethを使っていたのでこの辺で無効化
$ sudo systemctl disable dhcpcd.service
$ sudo systemctl disable dhcpcd@eth0.service
$ sudo netctl switch-to bonding
$ sudo netctl enable bonding
(もしかしたら再起動必要かも)
$ sudo reboot
$ ip link
でbond0となってるのが論理インターフェース.MACアドレスがあるはずなのでDHCPサーバで固定IP書く場合はメモる.
あとはスイッチ側の設定もやって二本目を繋ぐ.
実験
簡易的に2Gbpsになっていることを実感したかったのでやっていく
鯖でnginx立ち上げてその大容量ファイルをクライアントでwgetでもってくる.
残念な事にクライアントについてはリンクアグリゲーション出来ていないので,複数のクライアントで同時にDLする.
参考ページ
http://carpediemjournal.blog.fc2.com/blog-entry-26.html
https://qiita.com/toshihirock/items/6cb99a85d86f524bc153
$ sudo pacman -S nginx
RAMディスク作成
$ mkdir /usr/share/nginx/html/ramdisk
$ cd /usr/share/nginx/html/
$ sudo mount -t tmpfs -o size=5000M ramdisk ./ramdisk/
HDDの性能わからんかったからRAMディスク作ったけどいらないかもね
ダミーファイル作成
$ cd ./ramdisk
$ sudo dd if=/dev/zero of=4G.dummy bs=1M count=4000
$ sudo systemctl start nginx
あとはクライアント2台以上で同時に
$ wget -o /dev/null http://serversIPaddr/ramdisk/4G.dummy
両者ともに111MB/s出てるのでまあ大体いい感じでは?
以上
LinuxにおいてSDカードを挿した際に/dev下に出現しない場合の対処法
へべれけです.
これまでArch Linuxをずっと使ってきたわけですが,そこまで悩むことは存在しませんでした.しかし,実は使い始め当初から少し気になっていつつも放置していたのがSDカードを挿した際に/dev下にそれが出現せずマウントできないと言うものでした.
私は今までこれについてPCを再起動することで解決していたのですがこれは作業途中においてはそこそこストレスになるやり方でした.そこで今回はPCを再起動せずにSDカードを/dev下に出現させる方法について記述していきます.
解決への糸口となる情報をくれた友人へ,ありがとう助かった.
参考にしたページ
http://yper.seesaa.net/article/449217218.html
本来であればSDカードをスロットに挿入すると/dev/mmcblk0とその中の/dev/mmcblk0p1その他が出現する.出現しなかったらまず
$ lsmod|grep mmc_block
存在しなかったら参考ページ同様
$ sudo modprobe mmc_block
私の環境下ではそれでも出現しなかったので
$ sudo modprobe -r rtsx_pci_sdmmc
$ sudo modprobe rtsx_pci_sdmmc
としたら/dev/mmcblk0の出現を確認できた.なお,このブログを書いている現在,そもそもの/dev下に出現しない症状を再現できていない.
暇だったのでスクリプトを書いてコマンド化しといた.タイトルの症状が発生した時にこのコマンド打てば何とかなるはず
コマンド化の参考
http://bobbyquine.hatenablog.com/entry/2018/03/24/164602
$ vim ~/Command/sdreload
#!/bin/bash
if df|grep /dev/mmcblk > null ; then
echo "sd card mounted. if you want reload, you have to unmount"
else
if lsmod|grep mmc_block > null ; then
echo "mmc_block is already loaded"
else
echo load mmc_block
modprobe mmc_block
fi
if ls /dev|grep mmcblk > null ; then
echo nothing to do
else
echo reload rtsx_pci_sdmmc
modprobe -r rtsx_pci_sdmmc
modbrobe rtsx_pci_sdmmc
fi
fi
先述のとおり解決策を見つけた後に症状が再現できていないので動作未確認.多分動くんじゃね??責任はとらない.