Python:ランダムな文字列を作る

メモ。

UUID を生成。

>>> import uuid
>>> u = uuid.uuid4()
>>> u
UUID('b7206123-4b26-49ca-b33a-d0fb240c17f9')

Base32エンコードする。

>>> import base64
>>> b = base64.b32encode(u.bytes)
>>> b
b'W4QGCI2LEZE4VMZ22D5SIDAX7E======'

b はバイト文字列なので、文字列に変換。ついでに後ろに付いている = を取り去る。これは文字数合わせのためのパディングなので取ってしまって構わない。

>>> s = b.decode().rstrip('=')
>>> s
'W4QGCI2LEZE4VMZ22D5SIDAX7E'

さらに、見た目のランダムさを増すために、ラテン文字の大文字と小文字を混在させる。そのために、ランダムにラテン文字を小文字に変換する関数を定義。

>>> import random
>>> def down(c):
...     if random.choice([True, False]):
...         return c.lower()
...     else:
...         return c

これを、s の一文字ずつに適用。

>>> random_id = ''.join([ down(c) for c in s ])
>>> random_id
'W4qgCi2LEzE4vMz22D5sidAx7E'

これで OK。やや長いのが難点かな。

>>> len(random_id)
26

Ubuntu Server 22.04にSambaサーバをたてる(Dockerなしで)

Docker で Samba サーバをたてるのは諦めた。Ubuntu の上で直接 Samba サーバを動かすことにする。

まずはお決まりの apt update から。

takatoh@wplj:~$ sudo apt update

Samba サーバのインストール。

takatoh@wplj:~$ sudo apt install -y samba

設定ファイルを編集(バックアップをとってから)。

takatoh@wplj:~$ sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.orig
takatoh@wplj:~$ sudo vim /etc/samba/smb.conf

ワークグループの名前を変更したほか、ユーザー認証なしでアクセスできる public と takatoh のみアクセスできる restricted の2つの共有フォルダを作った。

もとの設定ファイルとの差分:

takatoh@wplj:~$ diff /etc/samba/smb.conf.orig /etc/samba/smb.conf
29c29
<    workgroup = WORKGROUP
---
>    workgroup = PANICBLANKET
241a242,257
> 
> [public]
>     path = /mnt/data/samba
>     writable = yes
>     force create mode = 0644
>     force directory mode = 0755
>     guest ok = yes
>     guest only = yes
> 
> [restricted]
>     path = /mnt/data/samba_takatoh
>     writable = yes
>     force create mode = 0644
>     force directory mode = 0755
>     valid users = takatoh
>     force user = takatoh

コメントを除く全体はこう:

[global]
   workgroup = PANICBLANKET
   server string = %h server (Samba, Ubuntu)
   log file = /var/log/samba/log.%m
   max log size = 1000
   logging = file
   panic action = /usr/share/samba/panic-action %d
   server role = standalone server
   obey pam restrictions = yes
   unix password sync = yes
   passwd program = /usr/bin/passwd %u
   passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
   pam password change = yes
   map to guest = bad user
   usershare allow guests = yes

[printers]
   comment = All Printers
   browseable = no
   path = /var/spool/samba
   printable = yes
   guest ok = no
   read only = yes
   create mask = 0700

[print$]
   comment = Printer Drivers
   path = /var/lib/samba/printers
   browseable = yes
   read only = yes
   guest ok = no

[public]
    path = /mnt/data/samba
    writable = yes
    force create mode = 0644
    force directory mode = 0755
    guest ok = yes
    guest only = yes

[restricted]
    path = /mnt/data/samba_takatoh
    writable = yes
    force create mode = 0644
    force directory mode = 0755
    valid users = takatoh
    force user = takatoh

で、共有用のディレクトリを作る。

takatoh@wplj:~$ sudo mkdir -p /mnt/data/samba
takatoh@wplj:~$ sudo chown nobody:nogroup /mnt/data/samba
takatoh@wplj:~$ sudo mkdir -p /mnt/data/samba_takatoh
takatoh@wplj:~$ sudo chown takatoh:takatoh /mnt/data/samba_takatoh

結果としてこうなった。

takatoh@wplj:~$ ls -l /mnt/data
total 8
drwxr-xr-x 2 nobody  nogroup 4096 May  6 18:13 samba
drwxr-xr-x 3 takatoh takatoh 4096 May  6 18:13 samba_takatoh

そして、smbd をリスタート。

takatoh@wplj:~$ sudo systemctl restart smbd

Samba にユーザーを作る。pdbedit コマンド。

takatoh@wplj:~$ sudo pdbedit -a takatoh
new password:
retype new password:
Unix username:        takatoh
NT username:          
Account Flags:        [U          ]
User SID:             S-1-5-21-3828460484-3255695466-1925772709-1000
Primary Group SID:    S-1-5-21-3828460484-3255695466-1925772709-513
Full Name:            takatoh
Home Directory:       \\WPLJ\takatoh
HomeDir Drive:        
Logon Script:         
Profile Path:         \\WPLJ\takatoh\profile
Domain:               WPLJ
Account desc:         
Workstations:         
Munged dial:          
Logon time:           0
Logoff time:          Thu, 07 Feb 2036 00:06:39 JST
Kickoff time:         Thu, 07 Feb 2036 00:06:39 JST
Password last set:    Fri, 06 May 2022 18:12:32 JST
Password can change:  Fri, 06 May 2022 18:12:32 JST
Password must change: never
Last bad password   : 0
Bad password count  : 0
Logon hours         : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

これでOK。Windows マシンからアクセスしてみると、ちゃんと \\wplj\public には認証無しで読み書きできる。\\wplj\restricted にはユーザー名とパスワードを要求され、正しく入力すれば読み書きできる。

無事完了。

[追記]

Samba のインストールと設定に際して、ファイアウォール関連は何もしていない。設定は次のようになっている。

takatoh@wplj:~$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere                  
137                        ALLOW       Anywhere                  
138                        ALLOW       Anywhere                  
139                        ALLOW       Anywhere                  
445                        ALLOW       Anywhere                  
22/tcp (v6)                ALLOW       Anywhere (v6)             
137 (v6)                   ALLOW       Anywhere (v6)             
138 (v6)                   ALLOW       Anywhere (v6)             
139 (v6)                   ALLOW       Anywhere (v6)             
445 (v6)                   ALLOW       Anywhere (v6)

Docker を使ってやってたときには何が悪かったのか、結局よくわからない。

DockerでSambaサーバをたてたけど外部からつながらない

昨日・今日といろいろ調べながら作業をしたけど、何が悪いのかわからない。もう Docker を使うのは諦めて、Ubuntu に直接 Samba サーバをインストールすることにしようと思うが、記録だけ残しておく。あ、「外部」ってのはローカルネットワーク上の別の PC のこと。

環境

ホストはこの間インストールした Ubuntu Server 22.04 だ。マシン自体は古いけど、いま Samba サーバになってるマシン(これは CentOS 7)はもっと古いので、これを置きかえるつもり。

  • Ubuntu Server 22.04 LTS
  • Docker version 20.10.14, build a224086349
  • docker-compose version 1.29.2, build unknown
  • dperson/samba (Samba の Docker イメージ)

Docker と docker-compose は Ubuntu のインストール時に一緒にインストールしたもの。Samba には公式の Docker イメージがないらしく、ググるとこの dperson/samba がよく使われてるようなのでこれにした。

Samba サーバをたてる

あちこちのページを参考にして、docker-compose.yml ファイルはこうした。

version: "3"

services:

  samba:
    image: dperson/samba
    container_name: samba
    restart: always
    ports:
      - "137:137"
      - "138:138"
      - "139:139"
      - "445:445"
    volumes:
      - "/mnt/data/samba:/mnt/public"
    command: [
      "-r",
      "-S",
      "-w", "PANICBLANKET",
      "-s", "public;/mnt/public;yes;no;yes;all"
    ]

これで Docker コンテナを起動してやる。

takatoh@wplj:~$ docker-compose up -d
Creating network "takatoh_default" with the default driver
Creating samba ... done
takatoh@wplj:~$ docker-compose ps
Name              Command                State                  Ports           
--------------------------------------------------------------------------------
samba   /sbin/tini -- /usr/bin/sam    Up (healthy)   0.0.0.0:137->137/tcp,:::137
        ...                                          ->137/tcp, 137/udp, 0.0.0.0
                                                     :138->138/tcp,:::138->138/t
                                                     cp, 138/udp, 0.0.0.0:139->1
                                                     39/tcp,:::139->139/tcp, 0.0
                                                     .0.0:445->445/tcp,:::445->4
                                                     45/tcp

次に、外部から接続できるようにホスト側のファイアウォールを設定する。Samba に関連するポートは、137、138、139、445 だ。ufw コマンドで接続を許可する。

akatoh@wplj:~$ sudo ufw allow 137
Rule added
Rule added (v6)
takatoh@wplj:~$ sudo ufw allow 138
Rule added
Rule added (v6)
takatoh@wplj:~$ sudo ufw allow 139
Rule added
Rule added (v6)
takatoh@wplj:~$ sudo ufw allow 445
Rule added
Rule added (v6)

そして、ファイアウォールを有効化。

takatoh@wplj:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

次のような状態になった。

akatoh@wplj:~$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere                  
137                        ALLOW       Anywhere                  
138                        ALLOW       Anywhere                  
139                        ALLOW       Anywhere                  
445                        ALLOW       Anywhere                  
22/tcp (v6)                ALLOW       Anywhere (v6)             
137 (v6)                   ALLOW       Anywhere (v6)             
138 (v6)                   ALLOW       Anywhere (v6)             
139 (v6)                   ALLOW       Anywhere (v6)             
445 (v6)                   ALLOW       Anywhere (v6)

これで完了(のはず)。

Windows から接続テスト

Samba サーバは出来上がったはずなので、Windows マシンから接続できるかテストしてみたところ、つながらない。共有フォルダどころか、コンピュータ(ホスト名は wplj)さえも見つからないと言われる。困った。

ネットワークの確認

Samba サーバをたてた wplj とは別の Ubuntu マシン(ホスト名は apostrophe)から、ネットワーク越しに接続できるのかを確認してみた。

まずは ping

takatoh@apostrophe:~$ ping wplj
PING wplj (192.168.2.12) 56(84) バイトのデータ
64 バイト応答 送信元 wplj (192.168.2.12): icmp_seq=1 ttl=64 時間=0.619ミリ秒
64 バイト応答 送信元 wplj (192.168.2.12): icmp_seq=2 ttl=64 時間=0.538ミリ秒
64 バイト応答 送信元 wplj (192.168.2.12): icmp_seq=3 ttl=64 時間=1.15ミリ秒
64 バイト応答 送信元 wplj (192.168.2.12): icmp_seq=4 ttl=64 時間=0.694ミリ秒
^C
--- wplj ping 統計 ---
送信パケット数 4, 受信パケット数 4, パケット損失 0%, 時間 3057ミリ秒
rtt 最小/平均/最大/mdev = 0.538/0.750/1.150/0.237ミリ秒

OK。そりゃそうだ、SSH で接続できてんだから。

なら、ポートが使えるかどうかを確認する nc コマンド。繋がるのがわかっている 22 番ポート(SSH)で試してみるとこうなる。

takatoh@apostrophe:~$ nc -vz wplj 22
Connection to wplj 22 port [tcp/ssh] succeeded!

では、Samba の使っている(はず)のポートではどうか。

akatoh@apostrophe:~$ nc -vz -u wplj 137
takatoh@apostrophe:~$ nc -vz -u wplj 138
takatoh@apostrophe:~$ nc -vz wplj 139
nc: connect to wplj port 139 (tcp) failed: Connection refused
takatoh@apostrophe:~$ nc -vz wplj 445
nc: connect to wplj port 445 (tcp) failed: Connection refused

137 番と 138 番で -u オプションを指定してるのは udp だから。何も出力されてないのは、接続できないからだ。tcp をつかう 139 番と 445 番は「失敗した」と明快に出力されてる。

一方のサーバ(wplj)側ではどうだろう。ss コマンドを使う。

takatoh@wplj:~$ ss -natu
Netid State  Recv-Q Send-Q                      Local Address:Port Peer Address:Port                                   Process                                  
udp   UNCONN 0      0                           127.0.0.53%lo:53        0.0.0.0:*                                                                               
udp   UNCONN 0      0                     192.168.2.12%enp1s0:68        0.0.0.0:*                                                                               
udp   UNCONN 0      0      [fe80::cad3:ffff:fe9d:2f5f]%enp1s0:546          [::]:*                                                                               
tcp   LISTEN 0      4096                        127.0.0.53%lo:53        0.0.0.0:*                                                                               
tcp   LISTEN 0      128                               0.0.0.0:22        0.0.0.0:*                                                                               
tcp   ESTAB  0      0                            192.168.2.12:22   192.168.2.14:58570                                                                           
tcp   LISTEN 0      128                                  [::]:22           [::]:*

Status の UNCONNLISTEN はそれぞれ udp、tcp の待受状態を表す。一つだけある ESTAB はつながっていることを表していて、これは SSH(22番ポート)だ。見事に Samba 関連のポートがない。

[追記]

いまためしたら、Samba のコンテナが起動してなかった。起動した上で ss コマンドを試すとこうなった。

takatoh@wplj:~$ ss -natu
Netid State  Recv-Q Send-Q                      Local Address:Port Peer Address:Port                                   Process                                  
udp   UNCONN 0      0                           127.0.0.53%lo:53        0.0.0.0:*                                                                               
udp   UNCONN 0      0                     192.168.2.12%enp1s0:68        0.0.0.0:*                                                                               
udp   UNCONN 0      0      [fe80::cad3:ffff:fe9d:2f5f]%enp1s0:546          [::]:*                                                                               
tcp   LISTEN 0      4096                              0.0.0.0:137       0.0.0.0:*                                                                               
tcp   LISTEN 0      4096                              0.0.0.0:138       0.0.0.0:*                                                                               
tcp   LISTEN 0      4096                              0.0.0.0:139       0.0.0.0:*                                                                               
tcp   LISTEN 0      4096                        127.0.0.53%lo:53        0.0.0.0:*                                                                               
tcp   LISTEN 0      128                               0.0.0.0:22        0.0.0.0:*                                                                               
tcp   LISTEN 0      4096                              0.0.0.0:445       0.0.0.0:*                                                                               
tcp   ESTAB  0      0                            192.168.2.12:22   192.168.2.14:58570                                                                           
tcp   LISTEN 0      4096                                 [::]:137          [::]:*                                                                               
tcp   LISTEN 0      4096                                 [::]:138          [::]:*                                                                               
tcp   LISTEN 0      4096                                 [::]:139          [::]:*                                                                               
tcp   LISTEN 0      128                                  [::]:22           [::]:*                                                                               
tcp   LISTEN 0      4096                                 [::]:445          [::]:*

Samba 関連のポートを待受けるようになった。けど、やっぱり他のコンピュータからはつながらない。

takatoh@apostrophe:~$ nc -u -vz wplj 137
takatoh@apostrophe:~$ nc -u -vz wplj 138
takatoh@apostrophe:~$ nc -vz wplj 139
nc: connect to wplj port 139 (tcp) failed: Connection timed out
takatoh@apostrophe:~$ nc -vz wplj 445
nc: connect to wplj port 445 (tcp) failed: Connection timed out

[追記ここまで]

まとめ

というわけで、どうやら Docker でたてた Samba のせいじゃなく、コンピュータ間で通信できてないように見える。SSH は問題なくつながってるのに何が違うんだ?