chiwata’s blog

たまに技術の話をします。

リモート飲み会のためのビデオ通話サーバを作る

コロナウイルスが蔓延している環境のなか、リモート飲み会をやる機会も増えたのではないでしょうか?

私も、大学生の頃の先輩から「リモート飲み会するぞー」と誘われ、zoomですか?skypeですか?のような話をしていたところ

先輩「jitsiってのが面白そうで使ってみたいからサーバを構築してみてくれ」

とのことだったので作った記録です

jitsiとは

Jitsi Meet https://github.com/jitsi/jitsi-meet

Jitsi Meet is an open-source (Apache) WebRTC JavaScript application that uses Jitsi Videobridge to provide high quality, secure and scalable video >conferences. Jitsi Meet in action can be seen at here at the session #482 of the VoIP Users Conference. The Jitsi Meet client runs in your browser, without installing anything else on your computer. You can try it out at https://meet.jit.si. Jitsi Meet allows very efficient collaboration. Users can stream their desktop or only some windows. It also supports shared document editing with Etherpad.

つまりはWebRTCでビデオ通話ができるOSS

構築

必要なもの

sshできる環境

サーバ(私はUbuntu 非力なものでよい) 1個

ドメイン 1個

作業

VMを作って、ドメインのAレコードをそのサーバのWAN側のアドレスに向けておいてください 今回私は、GCPのコンピュートインスタンスと、ムームードメインでとってあるドメインを使いました

サーバのfirewallなどの設定をしておきます各自でいい感じにしてください 使うのは下記の三つのポートです

80 TCP
443 TCP
10000 UDP

hostsに下記を追記

127.0.0.1 localhost 自分のドメイン

リポジトリを登録

echo 'deb https://download.jitsi.org stable/' | sudo tee /etc/apt/sources.list.d/jitsi-stable.list
wget -qO -  https://download.jitsi.org/jitsi-key.gpg.key | sudo apt-key add -

install

sudo apt update
sudo apt install apt-transport-https
sudo apt install jitsi-meet

証明書をつける

sudo /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh

とりあえずはこれで動く  

 動かしてみる

サーバにブラウザからアクセスします

f:id:chiwata:20200516201034p:plain
初期画面

この画面からもチャンネルを作れますが

https://自分のドメイン/任意の文字列

で勝手に部屋を作ってくれるのが便利

f:id:chiwata:20200516201901p:plain
demogamen

画面はこんな感じ、ほかのビデオ会議ツールとかと似たような感じで便利だし、zoomとかと違ってアプリを入れる必要もないのが楽

超簡単だけどここまで

bashでechoした複数行の値を配列に格納する

2020年になっても相変わらずのんびりやっています。

さて、いつも同期に聞かれて知らないものを調べてブログに書いていますが、今回もそれです。

複数行になっているデータを、下のように変数に格納しようとすると

#!/bin/bash

data="1
2
3"

declare -a array=()

echo "$data" | while read line
do
        array+=($line)
done

echo "${#array[@]}"
$ bash test.sh
0

このように要素数が0個に見えます 配列の追加の下に要素数を見る echo "${#array[@]}" を追加し確認してみると

$ bash test.sh
1
2
3
0

このように一度は格納されていますね これはパイプの後ろがサブシェルで実行されるので、親側での変数が変化していないため なので、親のシェルで実行されるように

#!/bin/bash

data="1
2
3"

declare -a array=()

while read line
do
        array+=($line)
done < <(echo "$data")

echo "${#array[@]}"
$ bash test.sh
3

このように標準入力にしてあげるとよいようですね

dateコマンドの謎

同期と話してて、

$ date '+%Y/%m/%d/-%H:%M' -d '201910180000  1day ago'
date: invalid date ‘201910180000  1day ago’

なんでこうなるの?と聞かれたので調べた、これは気にしたことなかった

date コマンドの +フォーマット は出力フォーマットなので、入力形式ではない

$ date '+%Y/%m/%d/-%H:%M' -d '201910180101  1day ago'
20191017/12/31/-00:00

こうしたときに気が付いたが、 20191018010120191017/12/31 と解釈されているのが原因だった

こういうこと、自分だけだとほとんど気にしないのでありがたい

シェルスクリプトでslackのslash commandを作成する

いろいろあって超短い時間でslackのslash commandを作ることになった。 普通だったらrubyとかgoとかで作るんだろうけど、一日で作るとなると勉強する時間が足りなかったのでbashで作ることにした

今回はconohaのVPS上にbashCGIとして動かす。

今回は説明用にhttpdの状態を確認するコマンドを作ります(ただし、httpdが起動していない場合コマンドがそもそも反応しないので、完全に説明用です。)

slackのslashcommandとは

リマインドとかで使うあれ api.slack.com

slackでアプリを設定する

ここからcreate new appをおして、アプリの名前を設定します Slack API: Applications | Slack

左側のFeaturesにあるslash commandを選んで、create new commandを選択

必要事項を記入します。

今回はRequest URLの欄には http://VPSのIP/cgi-bin/httpdstatus.cgi と入力しました。

保存したら。Install Appを押してワークスペースに反映してください。

サーバの設定をして、CGIを置く

httpd.confをCGIが動くように編集します。

<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options ExecCGI
    Require all granted
</Directory>
AddHandler cgi-script .cgi

次にスクリプトを置きます 今回は /var/www/cgi-bin/httpdstatus.cgi

#!/bin/bash
# statushttpd.cgi

echo "Content-type:text/plain"
echo

systemctl status httpd | while read line
do
        echo $line
done

一行ずつ渡してあげないと表示がそれっぽくならないので今回は while read line で渡しています。

試してみる

f:id:chiwata:20190728195033p:plain
slack

こんな感じになります。

その他

slackから送られてくるメッセージを受け取るには

slackからのリクエストには、このようなメッセージがついています

今回はわかりやすいように sed 's/&/\n/g' で改行していますが、本当は & 区切りでつながっています。

token=トークン
team_id=チームID
team_domain=ワークスペースのドメイン(slack.comの前)
channel_id=チャンネルID
channel_name=チャンネル名
user_id=コマンドを叩いたユーザーのユニークID
user_name=コマンドを叩いたユーザーの名前
command=%2Fstatushttpd(叩かれたcommand)
text=(コマンドの後ろについている文字列
response_url=レスポンスのURL
trigger_id=トリガーになったアクションのID

これはScriptに標準入力として渡されるため、read args で受け取ることができます。

トークンについて

このままだとslack以外からでも、このURLを叩かれた場合レスポンスを返してしまいます そのため、slack appのページのbasic informationのなかにある Verification Token を検証する必要があります。

レスポンスをほかのユーザにも見せたい場合

通常の設定だと、commandを叩いた本人にしかレスポンスが見えません。

echo "{ \"response_type\":\"in_channel\" , \"text\":\"メッセージ\" }"

このようにすることでほかのユーザーにも見せられるようになります。

メンションを飛ばしたい場合

レスポンス中で以下のように指定することでメンションをすることができます。ユーザーIDはslackからのリクエストに含まれるユーザーIDで、普段メンションで使っているIDではないので注意してください。

<@${USERID}> 

今回は以上です。

WSLのVagrantでconfig.ssh.insert_key = falseにするとsshできない

ansibleでプロビジョニングするのに、マシン一台一台に別の鍵が設定されるとうざいです。私は怒っています。

なので config.ssh.insert_key = false をすることに。すると vagrant ssh できなくなりした。むむむ。。。

結果としては、私がイメージしていた鍵の場所と、実際に見ている鍵の場所が違います。

$ vagrant ssh users001 
vagrant@127.0.0.1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic). 

権限がないといわれていますね。鍵の権限を見ます。

$ ls -la ~/.vagrant.d/insecure_private_key  
-rw------- 1 chiwata chiwata 1675 Jun 22 18:02 /home/chiwata/.vagrant.d/insecure_private_key 

600に設定しているので正しいはず。 いろいろ調べていくと、WSLのホームディレクトリの .vagrant ではなく、windowsのホームディレクトリを見ているようです。

$ ls -la /mnt/c/Users/user/.vagrant.d/insecure_private_key                                                                                                                                                                    
-rwxrwxrwx 1 chiwata chiwata 1675 Feb 18 15:07 /mnt/c/Users/user/.vagrant.d/insecure_private_key 

権限が777になっていますね。

$ chmod 600 /mnt/c/Users/user/.vagrant.d/insecure_private_key                                                                                                                                                                 
$ ls -la /mnt/c/Users/user/.vagrant.d/insecure_private_key                                                                                                                                                                    
-rwxrwxrwx 1 chiwata chiwata 1675 Feb 18 15:07 /mnt/c/Users/user/.vagrant.d/insecure_private_key 

権限の変更ができません。

$ sudo umount /mnt/c 
$ sudo mount -t drvfs C: /mnt/c -o metadata

一度アンマウントして、メタデータのオプションを付与して再マウントすると変更できるようになります 先ほどはWSLのユーザー名が所有者になっていましたが、なぜかrootになっているようなので、一緒にchownもします。

$ sudo chmod 600 /mnt/c/Users/user/.vagrant.d/insecure_private_key
$ ls -la /mnt/c/Users/user/.vagrant.d/insecure_private_key   
-rw------- 1 root root 1675 Feb 18 15:07 /mnt/c/Users/user/.vagrant.d/insecure_private_key 
$ sudo chown -R chiwata:chiwata /mnt/c/Users/user/.vagrant.d/ 

これでsshできるようになりました

$ vagrant ssh users001 
[vagrant@localhost ~]$

WSL、罠が多いような気がします。今回はここまで。

WSL+VagrantでつくったサーバをAnsibleでプロビジョニングしたい

最近、同期から「Linux勉強したいんだけど何したらいい?」とよく聞かれるのですが、私が教えてほしいです。

そこで、初めてインフラをやり始めたときに何してたかなーと思ったところ、ミニレンタルサーバっぽい何かを作ったことを思い出したので、そんな感じのやつを作ってみたら?と勧めてみました。

ミニレンタルサーバは、webサーバとリバースプロキシを二台ずつ、LBを構築してなんかいい感じに勉強するためだけのやつです。レンサバ的機能は一つも作りません、名前負けです。あと私の力では作れません。勉強します

ただ、自分が何もできないと悲しいので、最低限環境だけは整えたいと思います。 ちなみに、当時はitamaeでプロビジョニングしていた気がしますが、今回はAnsibleでプロビジョニングします。

WSLのUbuntuでVagrantを使いたい - chiwata’s blog

Vagrantwindowsで使えるようにするには前回の記事でやっていますので、続きからになります。

まず。Ansibleをインストールします

sudo apt update
sudo apt install software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt install ansible

今回は以下のようにして試します

. 
├── README.md
├── Vagrantfile
├── ansible.cfg
└── provisioning
    ├── hosts
    └── roles 
        └── users
            └── users.yaml

ansible.cfgに以下を記載

[default] 
inventory = provisioning/hosts

provisioning/roles/users/users.yamlは以下のように

---  
- hosts: users
  sudo: true
  tasks:
  - name: install apache
    yum: name=httpd

Vagrantfileは以下のように

Vagrant.configure("2") do |config|  
  config.vm.box = "centos/7"
  config.vm.define "users001" do |users001|
    users001.vm.network "private_network", ip: "192.168.33.10"
    config.vm.provision "ansible" do |ansible|
      ansible.playbook = "provisioning/roles/users/users.yaml"
      ansible.inventory_path = "provisioning/hosts"
      ansible.limit = "users"
    end
  end  
end

vagrant upしてみます

$ vagrant up 
/opt/vagrant/embedded/gems/2.2.4/gems/vagrant-2.2.4/lib/vagrant/util/which.rb:37: warning: Insecure world writable dir /mnt/c/ProgramData/DockerDesktop/version-bin in PATH, mode 040777
Bringing machine 'users001' up with 'virtualbox' provider... 
==> users001: Importing base box 'centos/7'... 
==> users001: Matching MAC address for NAT networking... 
==> users001: Checking if box 'centos/7' version '1902.01' is up to date... 
==> users001: Setting the name of the VM: mini_rental_server_users001_1560671696972_10166 
==> users001: Clearing any previously set network interfaces... 
==> users001: Preparing network interfaces based on configuration... 
    users001: Adapter 1: nat
    users001: Adapter 2: hostonly
==> users001: Forwarding ports... 
    users001: 22 (guest) => 2222 (host) (adapter 1) 
==> users001: Booting VM... 
==> users001: Waiting for machine to boot. This may take a few minutes... 
    users001: SSH address: 127.0.0.1:2222 
    users001: SSH username: vagrant
    users001: SSH auth method: private key
    users001:  
    users001: Vagrant insecure key detected. Vagrant will automatically replace
    users001: this with a newly generated keypair for better security.
    users001:  
    users001: Inserting generated public key within guest...
    users001: Removing insecure key from the guest if it's present... 
    users001: Key inserted! Disconnecting and reconnecting using new SSH key... 
==> users001: Machine booted and ready! 
==> users001: Checking for guest additions in VM... 
    users001: No guest additions were detected on the base box for this VM! Guest 
    users001: additions are required for forwarded ports, shared folders, host only
    users001: networking, and more. If SSH fails on this machine, please install
    users001: the guest additions and repackage the box to continue.
    users001:
    users001: This is not an error message; everything may continue to work properly,
    users001: in which case you may ignore this message.
==> users001: Configuring and enabling network interfaces... 
==> users001: Rsyncing folder: /home/chiwata/dev/mini_rental_server/ => /vagrant 
==> users001: Running provisioner: ansible... 
Vagrant has automatically selected the compatibility mode '2.0' 
according to the Ansible version installed (2.8.1).

Alternatively, the compatibility mode can be specified in your Vagrantfile:
https://www.vagrantup.com/docs/provisioning/ansible_common.html#compatibility_mode

    users001: Running ansible-playbook... 
 [WARNING] Ansible is being run in a world writable directory (/home/chiwata/dev/mini_rental_server), ignoring it as an ansible.cfg source. For more information see https://docs.ansible.com/ansible/devel/reference_appendices/config.html#cfg-in-world-writable-dir
[DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and  
make sure become_method is 'sudo' (default). This feature will be removed in 
version 2.9. Deprecation warnings can be disabled by setting 
deprecation_warnings=False in ansible.cfg.

PLAY [users] *******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.33.10] 

TASK [install apache] **********************************************************
changed: [192.168.33.10] 

PLAY RECAP *********************************************************************
192.168.33.10              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

ゲストにログインして、Apacheがインストールされているか確認します

[vagrant@localhost ~]$ httpd -v 
Server version: Apache/2.4.6 (CentOS) 
Server built:   Apr 24 2019 13:45:48

ちゃんとインストールされていますね。 sudo: trueは非推奨だそうなのでbecome: yesのほうがいいっぽいです。

ansible.limit = "users"をはじめ記載しておらず、はまってしまいました。 とりあえず動いたのでここまで