Docker MailserverでEmailサーバーを10分で立てる

何かしらサービスを申し込む際にはメールアドレスが必要になる。 Docker Mailserverを使って、Docker環境でさくっと立てる方法を書いていく。 今日日、どのISPでもクラウドでも、スパム対策でデフォルトでOutboundのport:25が開いていない。ので、何も考えずにサーバーを立てると、Emailの送信ができない。けど、受信だけできれば十分な場合が多いので問題ない。 送信できるEmail環境構築については、この記事で解説しています。 要件 基本的にdockerおよびdocker-composeの環境があればよい。 docker docker-compose 0. 今回想定する環境設定の値 項目 値 メールサーバ OS Ubuntu Linux メールサーバ Public IP 11.22.33.44 作業ディレクトリ /home/ubuntu/docker-mailserver メールサーバのホスト名 mailserver.example.com メールアドレスのドメイン @m.example.com メールアドレス [email protected] 1. Linuxホストを用意する PublicからアクセスできるLinuxマシンを用意する。ここではAWSのEC2にUbuntu環境を想定する。 LinuxホストのPublic IP: 11.22.33.44 2. LinuxホストのNWポートを開ける 以下のポートの受信を許可する。 Inbound port: 25, 80, 143, 587, 993 EC2の場合はセキュリティグループの設定をする。 port:80はSSL証明書(Let’s Encrypt)の取得・更新のために開けておく。...

January 29, 2022

リモートマシンにいつでも3秒以内にsshログインする

sshコマンドの設定ファイルssh_configについてです。 ほったん 開発をやっていると、色々なサーバのシェルにリモート接続して作業を行うことが多い。 そんな時に、いちいちホスト名を調べて、鍵ファイルパスを確認し、sshコマンドを叩くというのは骨が折れます。もっとも、こんな単純作業に無駄な時間と体力を使っている場合ではありません。 例えば、リモートホストに適当にニックネームをつけておいて、例えばAWSのいつも使うインスタンスであればawsなど、そうして、ssh awsだけでリモート接続できるようにしておけば便利です。 あ、awsマシンに入る必要があるな、と思いつき、 ターミナルを開いて、 何も思わず、% ssh awsと叩く ログイン完了 で、3秒以内にログインできるようになります。 このssh awsコマンドを実現するための設定を見ていきます。 ssh_configファイル sshコマンドはデフォルトで~/.ssh/configを設定ファイルの一部として読み込みます。このファイルの中に、リモートホストへのログイン情報を書いておくと、上記のようなssh awsだけでログインできるようになります。 例えば、以下のようなリモートホストがある場合を考えてみます。 sshのIPアドレス: 12.34.56.78 sshのポート番号: 22 ログインユーザー名: user001 ログインの秘密鍵のパス: ~/.ssh/my-ssh-key このホストをawsという名前にして、以下の設定を~/.ssh/configに書いておきます。 Host aws Hostname 12.34.56.78 User user001 Port 22 IdentityFile ~/.ssh/my-ssh-key 以降はターミナルを開いて、ssh awsコマンドですぐにログインできます。 % ssh aws user001@instance-1:~$ ちなみに、他のsshのオプションはコマンド時にアドホックに追加可能です。 例えば、上記のawsホストに対して、追加でPortForward(例えば、localのport 8080をawsマシンのport 80にforward)を追加する場合は以下のように書けます。 % ssh aws -L8080:localhost:80 このようにシンプル・クイックにリモートにログインできるようになりました。 もちろん、このリモートホストの設定は複数描けるようになっています。 また、sshの各種オプションも一緒に書けるようになっています。 Host aws Hostname 12.34.56.78 User user001 Port 22 IdentityFile ~/.ssh/my-ssh-key Host gcp Hostname 11....

January 28, 2022

MultipassでM1 MacでもVagrant的にLinux仮想マシンをサクッと立ち上げる

Linuxの仮想環境 on M1(Apple Silicon) Apple SiliconのCPUを搭載したMac(通称"M1 Mac")を購入して、ファンレスでこのパフォーマンス、しかも熱くならない、バッテリー持ちがすごい、何に安い!、などなど、いい意味で衝撃を受けています。 一方で、エンジニア目線で気になるのは、ちゃんと開発ツールが動くのか、だと思います。 特に、LinuxのVM環境は必須で、作っては壊し、壊しては作る(Build & Scrap!)をカジュアルにできないと何かと困ります。これまではVagrant+VirtualBoxでその環境を整えてきたのですが、M1 Macではこれができません。 Multipass そうこうしているうちに、Ubuntuでお馴染みのCanonicalからMultipassというツールが出てきました。これは、Ubuntuに限られるのですが、Vagrant的にLinux VMを作って・壊すというのがすぐにでき、かつ、M1 Macにも対応しているので、Vagrantのワークフローと同様のことがM1 Mac上でできてしまします。 以下、Multipassの簡単な使い方を見ていきます。 Multipassのインストール Multipassの公式ページもしくはgithub Releaseからバイナリ(パッケージ)をダウンロードできます。通常通り、ダブルクリックでインストールできます。 インストール後はターミナルからコマンドを実行して確認できます。 % multipass version multipass 1.8.1+mac multipassd 1.8.1+mac 基本的な使い方 起動・shellログイン・停止・削除など一通りやってみます。 起動 まず、利用可能なUbuntuのversionをリストします。 % multipass find Image Aliases Version Description 18.04 bionic 20220104 Ubuntu 18.04 LTS 20.04 focal,lts 20220118 Ubuntu 20.04 LTS 21.10 impish 20220118 Ubuntu 21.10 LTS(Long Term Support)版と最新のversionは利用可能になっています。 Ubuntuのversionを指定してVMを起動します。指定しない場合は一番新しいLTSが使われるようです。 ## デフォルトのUbuntu LTSで立ち上げる % multipass launch -n my-ubuntu-123 ## Ubuntu focalで立ち上げる % multipass launch -n my-ubuntu-123 focal ## CPU=2コア, RAM=2GB, Disk=10GBで立ち上げる % multipass launch -n my-ubuntu-123 -c 2 -m 2g -d 10g Shellにログインする % multipass shell my-ubuntu-123 ubuntu@my-ubuntu-123:~$ pwd /home/ubuntu ....

January 25, 2022

Redashをarm64系で動かす

最近M1 macを買ったり、Raspberry PIで遊んだり、AWSのGraviton2の無償インスタンスを試したり(2021年末で終了)、Oracle CloudのAmpere A1 Computeをゲットしたりと、気づくとARM64系の環境に囲い込まれてしまいました。Intel系は仕事で使っているMacbook Proくらいですかね。 いざ、RedashをARM上で動かそうとしたら、公式のDocker imageはamd64のみの対応で、そのままでは動かすことできないことがわかりました。 手元にあるARM64環境でDocker Imageをbuildしました。コードは以下のgithubレポにあります。 github: redash_for_arm64 すでにBuildしたImageはgithubのcotainer registry上においたので、そこからpullできます。

January 9, 2022

「どうやって子どもたちにネットを開放していくか」問題

こんばんわ。今回は、Cloudflareが無償で提供しているDNSサービス"1.1.1.1 for Families“を使って、家族が誤って変なサイトに接続しないようにする方法について取り上げます。 家族(子ども)とネット 家庭に子どもができるとインターネット環境へのアクセスを考えることが度々あります。 まず、デバイスから。初めのうちは、TV内蔵のYoutubeを見始めて、次いで、親のスマホをちょっと触り、どんどん「通常」のインターネットに近寄っていきます。ちょっと学校の宿題を調べたいからスマホ使わせてよ。iPadでAmazonの検索を始めるとか。 ここまでくるとやはり心配になります。変なコンテンツ(アダルト・フィッシングサイト)にアクセスしてないか、とかです。Appleとか使っていると、Parental Controlという機能があって、子どもが変な操作したり・コンテンツにアクセスする制限がある程度できるようになっているのですが、あくまでApple系サービスとかに限った話になります。Safariブラウザ開いてでどんなコンテンツにアクセスしているのかとかまでは見てくれません。 そういった問題への一つの対策としてCloudflareが無償で提供しているDNSサービスの"1.1.1.1 for Families"が使えます。 DNSでブロックするサービス “1.1.1.1 for Families” 簡単にいうと、怪しいサイトへアクセスするときに、名前解決時点で「このサイト怪しいのでブロックするぜ」というサービスです。設定方法は簡単で、PCもしくは家庭内のルーターでDNSサーバ(リゾルバ)の設定を以下に設定するだけです。 1.1.1.3 1.0.0.3 # IPv6なら 2606:4700:4700::1113 2606:4700:4700::1003 このDNSを使用しているときに、ブラウザでアダルトサイトにアクセスすると以下のようになります。 以上が概要です。以下、このサービスの仕組みと家庭内のルーターに設定する方法などを見ていきます。 仕組み 先ほど触れた通り、仕組みは名前解決を使用したアクセス制限になります。名前解決とは、インターネットのサイト名(例: www.google.com)からそのサイトのウェブサーバのIPアドレスを調べる仕組みになります。通常インターネットの世界ではIPアドレスで通信を行います。例えば、192.168.1.1とか8.8.8.8などの表記を見かけることがあると思いますが、これがIPアドレスです(今回の例はIP version4というのもので略してIPv4と書きます)。 私の環境からwww.google.comのIPアドレスを調べると、 % dig www.google.com +short 216.58.197.196 となって、216.58.197.196となります。 この、サイト名とIPアドレスの変換をしてくれるのがDNSです。通常、このDNSはデフォルトで使っているプロバイダ(ISP)指定のDNSになっているのですが、今回はそれを上記のCloudFlareが提供するDNSに変更するということになります。 そうすると、普段ネットでどこかのサイトを開くときに、この名前解決のリクエストがCloudFlareのDNS上に届き、このDNS上で「怪しい」もしくは「アダルトサイト」と判断されたサイトの場合にはそのサイトのIPアドレスに変換しない(応答しない)ことでサイトへの接続を遮断してくれるのです。その結果がさっきのスクショになります。 家庭内のルーターへの設定例 家庭内のネット接続では家の中にルーターがあって、そこにプロバイダ指定のDNSがデフォルトで設定されています。私の家だとNuroを契約していて、プロバイダ(Nuroのプロバイダは実質So-net)が送ってきたルーター(ZTE製F660A: 実質レンタル品)に設定方法を書いていきます。他者の場合でもほとんど同じように設定できると思います。 まず、ブラウザでルーターの管理を開きます。大抵192.168.0.1もしくは192.168.1.1になっていることが多いと思います。 このルータの場合、メニューから アプリケーション»DNSサービス»DNS に行くと、DNS設定の項目があるので、上記のDNSを設定します。 もしくは、DNS設定はDHCPという項目に含まれることが多いので、他のルータの場合も探してみてください。 あとは設定ボタンを押せば完了です。設定直後は、PCやタブレット・スマホの場合、一度Wifi・ネットワークをOFFにしてら再度ONにするなどしないとDNS設定が変わらないかもしれません。 テスト テストは簡単です。ブラウザを開いて、怪しいサイトを開いてみれば分かります。サイトの判定は全部CloudFlareがやっています。 誤判定 正規のサイトに行っているのに遮断されることがたまにあります。今まで発見した誤遮断されたサイトとして楽天カードの申込ページなどがありました。まあ、変なサイトにつなぎに行くより(False negative)、正規のサイトに繋ぎに行かない(False positive)方が安全といえば安全かもしれませんが。 その他 上記で詳しく書きませんでしたが、この"1.1.1.1 for Families"には2つのモードがあります。「マルウェアサイトのみをブロック」するモードと「マルウェアサイトとアダルトサイトをブロック」するモードです。違いは設定するDNSサーバのIPアドレスなので、切り替えも簡単です。詳しくは公式サイトのアドレス設定を見てください。 あと、ブロックされるサイトの名前解決クエリに対してどのようなレスポンスが返ってきているのかを見てみましょう。 % dig jp.pornhub.com @1.1.1.3 ; <<>> DiG 9....

May 24, 2020

lftpでファイル転送系をまとめる

lftpについて 概要 次の3点: ファイル転送系のCUIでいろいろ使える(FTP, SFTP, FTPSなどファイル転送系のプロトコルはだいたいサポートされている mirrorコマンドでリモート/ローカルでファイル・ディレクトリを丸ごと同期することができる(rsync) 並列転送をサポートしているので,LONG FAT PIPEな環境でも高速にファイルが転送できる. インストール だいたいのプラットフォームでパッケージが用意されている. macOSだとbrewで,ubuntuだとapt-getで瞬時に導入できる.おそらくCentOSのyumでもパッケージが提供されているはず. macOS$ brew install lftp ubuntu$ sudo apt-get install lftp Hellow World! 1. FTP系のコマンド FTPコマンドがカバーされている. get put mput lcd !pwd その他もろもろ ということで,FTP意外のプロトコルを使う場合でも,基本的にコマンド操作を統一化できる.webホスティングサービスによっては,ファイル転送で許可されているプロトコルが異なるのだが,lftpを使っておけばそこら辺を吸収することができる.引越しが楽になる. あとは,SFTPがサポートされているので,サーバ側にsshd(+sftpの許可設定)を立てておけば,セキュアにファイル転送が可能になるのがうれしい.tab補完も効いているので,shellでインタラクティブに作業するときには助かる. 例えばsshdが立っているリモートのサーバ(remote.site.com)からhtmlファイルをダウンロードする(mgetする)には,以下のような感じになる. $ lftp -u user123 sftp://remote.site.com Password: <= パスワード入力 lftp [email protected]:~> ls drwxr-xr-x 4 user123 user123 4096 Mar 21 13:56 . -rw------- 1 user123 user123 9296 May 31 12:54 .bash_history -rw-r--r-- 1 user123 user123 220 Jan 5 00:03 ....

May 31, 2017

PythonでExifをいじる

exifreadというライブラリが有名らいし.githubにもあるし,pipでも入る. EXIF付きのファイルをopenして,process関数に渡すと,EXIFに含まれるtag, keyをパースしてくれる. これを利用して,flickrから落としてた写真のファイル名のプレフィックスに日時を入れてソートするためにコーディングした. import exifread import sys import os ''' Inserting taken-date-time at the beggining of base filename. ''' def getTakenDateTime(filename): with open(filename) as f: tags = exifread.process_file(f) for tag in tags.keys(): if 'DateTimeOriginal' in tag: #print 'key=%s, val=%s' % ( tag, tags[tag] ) datetime='%s' % tags[tag] datetime=datetime.replace(':', '') datetime=datetime.replace(' ', '_') return datetime if __name__ == '__main__': for i in sys.argv[1:]: basename = os.path.basename(i) dirname = os.path.dirname(i) datetime = getTakenDateTime(i) src = i dst = '%s/%s_%s' % (dirname, datetime, basename ) print basename, dst os....

August 27, 2015