hostname, domainname設定のメモ(CentOS7)

ホスト名やドメイン名の設定はディストリビューションやバージョンによって推奨が異なっており、ややこしい。 設定ファイルの動作を確認したのでメモしておく。

TL; DR

環境

$ cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core) 
$ cat /etc/postfix/main.cf
myorigin = $mydomain
以下略

設定

とする。

# echo hoge.example.com > /etc/hostname
# systemctl restart NetworkManager

/etc/hostsに設定も入れた方がいいのかは不明。入れている記事が多いが、動作したので気にしないことにする。

ドメイン名を/etc/sysconfig/network-scripts/ifcfg-eth0や/etc/resolve.conf に記載する記事もあるが、古い作法のようである。

確認

$ hostname
hoge.example.com

$ hostname -f
hoge.example.com

$ dnsdomainname
example.com

$ cat /etc/resolve.conf
# Generated by NetworkManager
search example.com
nameserver 192.0.2.1

失敗例

上記に加え、/etc/hostsに以下を設定

127.0.0.1 localhost localhost.localdomain hoge.example.com

結果

$ hostname
hoge.example.com

$ hostname -f
localhost

$ dnsdomainname
example.com

FQDN表示がlocalhostとなる。

127.0.0.1 hoge.example.com localhost 

が正しいようである。

その他

ホスト名の設定前はメールの送信元が user@localdomain.localdomain となっていた。

パスワード強度判定の正規表現と肯定的先読み

数字アルファベット大文字小文字を含む8文字以上の文字列にマッチする正規表現のメモ

条件は正規表現で書くと ^(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])[!-~]{8,}$ となる。

これを可視化すると、

https://jex.im/regulex/ f:id:smitch:20200208123436p:plain

https://regexper.com f:id:smitch:20200208123431p:plain

となるが、肯定的先読みがregulexでは表示されていない。 regexper.comでもpositive lookaheadの表記があるのみ。

正規表現なんだからオートマトン で書けるでしょって思ったのだが、結構大変なようである。

中身をちゃんとは読めていないのだが、大きさmの正規表現が状態数O(22m)の決定的有限オートマトンになるらしい。

先読み付き正規表現の有限状態オートマトンへの変換 森畑 明昌, PPL2011 https://www.jstage.jst.go.jp/article/jssst/29/1/29_1_1_147/_pdf

windows server 2016 datacenterのセットアップメモ

TL; DR

やったこと

  1. windows update
  2. 管理者アカウント(非administrator)の追加とadministratorの停止
  3. sambaセットアップ
  4. firefoxインストール
  5. remote desktop用証明書のセットアップ(let's encrypt)
  6. remote desktopのポート変更
  7. 不要なfirewallルールの削除

windows update

  • 説明不要

管理者アカウント(非administrator)の追加とadministratorの無効化

  • コンピュータの管理→ローカルユーザとグループ→ユーザから新規アカウントを作成。Administrator権限を付与
  • 新規アカウントでサインインし、administratorを無効化

sambaセットアップ

windows -> samba server

  • アクセス先:Centos7 samba Version 4.8.3

エクスプローラにて¥¥を入力し、認証情報を入力

はまったこと

  • ネットワークドライブの割り当てができない。ユーザ認証後、「ネットワーク名が見つかりません」のエラーが出る(未解決)
  • windows serverへはmacからリモートデスクトップしているのだが、「¥」が普通にキーボードから打つと特殊記号扱いされる(?)。スクリーンキーボードから「¥」を入力することで解消

外部 -> windows server

  • 共有したいフォルダを作成し、右クリック→共有にて設定する
  • 外部(centos)にて以下を実行
sudo yum install samba-client cifs-utils
sudo mount.cifs //<server ip address>/<path to share folder> <mount point> -o "user=<user name>,uid=$(id -u),gid=$(id -g)"

sudo mount したときに、ログインユーザーでのパーミッションをつける - IKB: 雑記帳

firefoxインストール

IEではセキュリティ警告が多いのsamba経由でfirefoxインストーラを渡し、インストールする

remote desktop用証明書のセットアップ(let's encrypt)

remote desktopのポート変更

  • regeditにてHKEY_LOCAL_MACHINE¥SYSTEM¥CurrentControlSet¥Control¥Terminal Server¥Winstations¥RDP-Tcp中のPortNumberを書き換える
  • firewallにて指定したTCPポートの受信ルールを作成する ※デフォルトのリモートデスクトップのルールはポート番号が変更できない
  • サーバを再起動

不要なfirewallルールの削除

  • 受信の規則でRDP、SMB関連、ICMP関連以外は全て無効化
  • 送信規則は今後検討

その他

  • メモリ1GBのVPSなので動作が不安だったが、ちゃんと動く。

anaconda on mac にてpython環境の新規構築ができない

macでanacondaを利用してpythonの環境を作ろうとしたが、anacondaで新規にpythonのインストールができない不具合に遭遇したので対応のメモ

環境

macOS Mojave 10.14.6(18G95)
MacBook Air (Retina, 13-inch, 2019)

事象

anacondaをインストール後、GUIのanaconda-navigatorから新規にpythonの環境をインストールしようとしたところ、 ダウンロードが進んでいる様子はあるが、pythonの一覧に新規環境が追加されない。

対策

以下の内容にて構築できたが根本原因は不明。

1 terminalの起動

2 terminal上でanaconda-navigatorの起動

terminal上で、 /anaconda3/bin/anaconda-navigator にてanaconda-navigatorを起動

3 環境の構築

anaconda-navigatorの Environments⇒Createからpythonの環境を作成する。 HomeからJupyterlabもインストールしておく

4 通常通りanaconda-navigatorを利用

以降はterminalから実行しなくても使える

permission系のエラーかなという予想ではあるが、terminalから実行すると正常動作したので、ちゃんとデバッグ出来ていない。

再インストールしても同様の現象が発生するので再現性もあった。

python注意点まとめ

思うところあってpythonを真面目に勉強したので、ハマったことなどまとめ。

なお、特にこだわりはないけど環境はpython2

TL: DR

  • FizzBuzzブラックジャックとヒープツリーを実装してみた
  • インデントを揃える。話はそれからだ
  • phpのvar_dumpに相当する関数はない
  • unittestは標準で用意されている
  • for文を使うときはfor i in range(0, n):とする。rangeがなくても動くが、期待通りに動かない
  • implicit falseが推奨らしい

FizzBuzz

短いのでインラインで。 慣習的なものはよくわからないけど多分そんなに違わないと思う。

import sys

def fizzbuzz(n):
    ret="1"
    for i in range(2, n+1):
        if (i%15)==0:
            ret+=" FizzBuzz"
        elif (i%3)==0:
            ret+=" Fizz"
        elif (i%5)==0:
            ret+=" Buzz"
        else:
            ret+=(" "+str(i))
    print(ret)

実行結果は

$ python fizzbuzz.py 15
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz

となる。

ブラックジャック

プログラミングのステップの1つとしてブラックジャックを実装してみるのがいいみたいなので書いてみた。

こっちもレギュレーションをきちんと確認していないので雰囲気で実装。

コードはここに

https://github.com/smitch/python-practice/blob/master/blackjack.py

結構楽しいので、時間があるときにもうちょっと詰めたい。

カードカウンティングとかも面白そう。

unittest

ブラックジャックを書いた後にunittestが標準であることに気づいた。

unittest.TestCaseを継承したクラスを作成して、メソッド名がtestで始まるメソッドを実装すればunittest.main()を呼び出すだけでテストメソッドを実行してくれる。

メソッド名がtestで始まるメソッドを実装すればよい。(大事なことなので2回言いました)

継承してメソッド実装すると、実装したメソッドを自動実行するっていうのも面白い仕様だと思った。時間があるときにunittestの実装もみてみよう。

なお、pythonの実行時に-vオプションを付けることでテストの情報が出力される。

詳しいことはここに

unittest --- ユニットテストフレームワーク — Python 3.7.4 ドキュメント

ヒープツリー実装

そこそこ真面目なヒープツリー実装のはず。。。

python標準ライブラリのheapqはリスト実装だけど、今回はグラフを使ったツリー構造での実装。

https://github.com/smitch/data_structure_and_algorithm/blob/master/tree/heap_tree.py

iteratorとyield

yieldを使うと明示的に状態を持たなくてもiteratorが実装できる。

yieldでヒープツリーのDFSを実装するとこんな感じ。

    def dfs_iter(self, current=None):
        if current is None:
            current = self.root
        yield current
        if current.left is not None:
            for i in self.dfs_iter(current.left):
                yield i
        if current.right is not None:
            for i in self.dfs_iter(current.right):
                yield i
        raise StopIteration

最初、yieldはreturn的な動作だと思ったが、returnとは切り離して考えた方が良さそう。

yieldの流れは、

  1. yieldを使うメソッドを呼び出すと、generatorが返ってくる。

  2. 得られたgeneratorのnext(next)メソッドを呼び出すことで、実際のメソッドの中身が実行される。

となる。

for文と合わせて使うと自然に使える。

ちょっと特殊な感じがするけど、慣れると便利そう。

pydoc

pydoc <module name>

にてドキュメントが生成される。

モジュール名はファイル名から.pyを除いたもの

pycheck

pipでインストールする。

pychecker <file name>

にて構文のチェックを行なえる。

細かい設定はまだ追えていない。

pylintとかも調べたい。

python style guide

pythonのスタイルは大きくgoogle styleとnumpy styleの2つがあるらしい。

今回はgoogle styleを参考にした。

https://github.com/google/styleguide/blob/gh-pages/pyguide.md

var_dump

pprint.pprint(vars(a))などでインスタンス変数の一覧を出力できる。

内部的にはvarsはa.__dict__を出力している模様。

なお、printを実行すると__str__が呼ばれる。

特殊属性、メソッドは把握しきれていないので、きちんとまとめたい。

このサイトはかなり参考になった。

特殊メソッド名 - Dive Into Python 3 日本語版

implicit falseとNone

  • 変数が0,[],False, None等の場合の分岐はif a:の表記が推奨。ただし、0Falseを区別したい場合には使えない。
  • 変数とNoneの比較はしてはいけない。if a is Noneと書く。

NoneTrueでもFalseでもない。ちょっと人工的な例だけど下のようなコードを書くとハマる。

if a == True:
    print "true"
elif a == False:
    print "false"
else:
    print "a is neigher True nor False!"

python2とpython3の違い

ここまでやってみて気づいた点

  • printがpython2では構文だがpython3では関数
  • イテレータの次の要素の取得がpython2ではnextだがpython3では__next__
  • python2ではprintで末尾に必ず改行が入る。

今後やりたいこと

  • assertに引っかかったらプログラム停止して、インタラクティブモードになるようにしたい。どこかのサイトに実装があったはず。

スピードキューブで1分以内に揃えられるようになった

「時間かければ揃えられる(2分以内くらい)」→「1分以内に揃えられる」までトレーニングしたのでメモ書き。

1分以内は手順覚えて練習すれば出来るみたいな記事があるけど、実際どれくらいのレベルなのかを書いておく。

TL; DR

  • 手が常に動く程度にキューブの状態を確認出来るようになれば60秒以内は達成できる

  • 揃え方のパターンは覚えこまなくてもいい(F2Lのパターンなど)

  • タイマーアプリを活用する

現在のレベル

基本的にはLBLやCFOPな揃え方をしているが、揃え方が我流なので一般的なのより効率悪いかも。 いろいろ考えてやっていくのが楽しいというスタイルなので、今の段階では覚えるのはあまりしない。 1分切れるようになったので、おいおい一般的なのも覚えていきたい。

具体的な手順は時間があるときにまとめたい。

やっている揃え方とおおよその所要時間

  • cross

とにかく揃える。それだけ。目標10秒以内だけど15秒くらいかかることもある。

現状のレベルだと、インスペクションの15秒ですべて読みきるのは結構きつい。 大体3つは読んで、最後は場当たりで揃えることが多い。ひどい時は2つまでしか読めないが、その際は1分はかなりきつい。

  • F2L

当初は1層目、2層目の順でやっていたけど、入れられるところからこだわらずにやったほうが速かった。

キューブを探すのに時間が掛からないようにする。

現状だと、次に揃えるキューブの場所のあたりはつくけど、向きとかが正確に把握できていないので、 一旦動きを止めて確認する必要がある。このあたりは今後の改善点

ここまでで35秒くらいかかる。

  • OLL(コーナーキューブ)

まず、last layerのコーナーキューブの位置を調整する。 PLLの前にするのは理由が2つある。

1つ目は単純に、いわゆるUパームの手順を知らないから。つまり、PLLしてからPLLされた状態に戻しつつコーナーキューブの入れ替えをする手順を知らないからやっていない。

2つ目は、こっちのほうが入れ替えの操作回数は少なくなると思っているから。キューブの状態確認に時間がかからなければ、PLLを気にしなくていい分、早めに操作したほうが手順が少ないと思う。

なお、エッジキューブの位置調整はこの段階ではしない。

だいたいここまでで43秒くらい。45秒までかかると後がきつい。

  • PLL

コーナーキューブとエッジキューブの上面の向きを揃える。

なお、コーナーとエッジキューブはそれぞれ独立した手順で揃える。

ここまでで50秒くらい。

  • OLL(エッジキューブ)

エッジキューブの並び次第で、同じ手順を0〜2回繰り返すことになる。

順調にできていないと手順2回だと1分以内はきつい。

タイマーアプリについて

スマホアプリが有能。

数は試してないけどこれが良かった。

play.google.com

機能としては

  • タイマー機能

  • スクランブル生成

  • 記録の統計

があるので、かなり練習が捗る。

スタックタイマーのデザインになっているので雰囲気もそれっぽくなる。

改善点と今後の目標

40秒切るくらいまでは現状の改善でできそうな気がする。 具体的には、 - クロスはインスペクションで読みきって、10秒で確実に揃える。可能であればF2Lも少し読む。 - F2Lでコーナーキューブとエッジキューブを同時に揃える - OLLの手順が少なくなるようF2Lの手順を調整する - OLL、PLLでキューブの状態を逐次確認しなくても良くなるよう、連続した手順を行えるようにする

F2Lの短縮が大きく効きそうなのでそこを重点的にしたい。 パターンごとの手順を覚えなくても、キューブの状態の把握の向上と、特定の手順を行った時にその他のキューブがどう動くのかを読めるようになれば自然とF2Lで出来るようになると思う。

とりあえず1分切ったので、40秒まではぼちぼちなペースでやっていくつもりである。 手順は意識せずに、継続練習でキューブの状態把握の向上を半年くらいやってみようと思う。

postfixの設定を見直した

TL; DR

  • 自前のメールサーバから送ったメールがgmailで”暗号化されませんでした”と表示されるので、tls関係の設定を変更した
  • postfixの設定のプレフィクスには”smtp_”と”smtpd_”の2種類がある
  • postfixの設定のプレフィクスには”smtp_”と”smtpd_”の2種類がある (大事な事なので…以下省略

smtpとsmtpd

メーラ→メールサーバ(postfix)→gmailの流れでメールを送信するケースを考える。

このとき、メーラ→メールサーバ間が”smtpd_”の設定、メールサーバ→gmailが”smtp_”の設定が該当する。

よって、gmail向けにTLSを使う場合は、”smtp”の設定でtlsを有効にする。

設定

メーラとgmail向け両方にtlsを有効にするよう設定をした。 証明書はLet’t encryptで取得しているのでそれを用いる。証明書更新時にはpostfixの再起動が多分必要。

なお、smtp_tls_CAfileは指定をしないとgmailの証明書がuntrustedとなる(ログに記録される)。

しかし、ログに記録されるだけで、httpsのように警告が出たりはしない。

unstrustedの場合に動作を変更する場合には、smtp_tls_security_levelでverifyを指定し、smtp_tls_verify_certで検証項目を指定する。

ただし、この動作はインターネットにメールを配送するシステムのデフォルト動作としては適切ではない。

また、この設定は、tlsで送信してもいいし、しなくてもいいという日和見tlsであるが、tlsを強制する設定も、インターネットにメールを配送するシステムのデフォルト動作としては適切ではない。

smtp_tls_security_level = may
smtp_tls_CAfile = /etc/pki/tls/cert.pem
smtpd_tls_cert_file = /etc/letsencrypt/live/<domain name>/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/<domain name>/privkey.pem
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_protocols = !SSLv2, !SSLv3
smtpd_tls_protocols = !SSLv2, !SSLv3
smtpd_tls_loglevel=1
smtp_tls_loglevel=1
smtpd_tls_received_header = yes

なお、postfix 2.3以降では“smtp_use_tls”を使わず、smtp_tls_security_levelを使うことになっている。

パラメータの詳細はman 5 postconfで見れる。

ウェブに比べてメールシステムの暗号化・証明書の扱いってゆるゆるですね。 そのうちメールにもtls必須とかの流れになるんでしょうか。