UniFi セキュリティゲートウェイを Adopt した後、デバイスにログインできなくなる

UniFiセキュリティゲートウェイを Adopt し、ステータスがCONNECTEDになった後にセキュリティゲートウェイ(192.168.1.1)へデフォルトアカウント(ubnt / ubnt)でHTTPS、SSHのログインができなくなった。Adopt 前はログインできていた。

フォーラムなどを検索すると Settings > Site の Advanced Features を有効にして Device Authentication を確認しろとの情報が出てくるが、手元のコントローラー(バージョン 6.0.36)ではDevice Authenticationが見つけられなかった。

結局 Settings > System Settings > Controller Configuration > Device SSH Authentication というところにSSHのユーザー名とパスワードを見つけた。HTTPSも同じユーザー名とパスワードでログインできた。

ちなみにDevice Authenticationが見つけられないのは「New Settings」がONになっていてベータ版の管理画面が有効になっていたからだった。

SESのSMTPパスワードの署名を作るRubyワンライナー

Amazon SES で SMTP を使う場合、ユーザー名は IAM のアクセスキーID、パスワードはシークレットアクセスキーを使った署名を設定する必要があります。

https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/smtp-credentials.html

RubyでSESのSMTPパスワードを作るワンライナー。AWS_SECRET_ACCESS_KEY、AWS_REGIONを適宜変更してください。

ruby -rbase64 -ropenssl -e 'puts  Base64.encode64([0x04].pack("c*") + ["AWS4" + "AWS_SECRET_ACCESS_KEY", "11111111", "AWS_REGION", "ses", "aws4_request", "SendRawEmail"].inject { |k, v| OpenSSL::HMAC.digest("sha256", k, v) })'

HerokuでRails+MySQLを使うときのdatabase.ymlの設定

Herokuで ruby の buildpack を使うと、以下の条件の場合に config/database.yml が自動的に作成される。

  • config ディレクトリがある
  • activerecord がインストールされている
  • 環境変数に DATABASE_URL が設定されている

データベースに ClearDB などを使う場合、DATABASE_URL を以下のフォーマットで設定する。

mysql2://<username>:<password>@<host>/<database>?<key>=<value>(&<key>=<value>)

例:

mysql2://username:password@us-xxx-xxx-xxxxxxxxxxxx.xx.cleardb.net/rails_production?encoding=utf8&pool=5&timeout=5000

database.yml の内容は rails console から ActiveRecord::Base.connection_config で確認できる。

irb(main):001:0>  ActiveRecord::Base.connection_config
=> {:encoding=>"utf8", :pool=>"5", :timeout=>"5000", :adapter=>"mysql2", :username=>"xxxxx", :password=>"xxxxx", :database=>"heroku_xxxxx", :host=>"us-xxxx-xxxx-xxxx-xx.cleardb.net"}

注意点

ClrearDBで Ignite (Free) や Punch ($9.99/mo) などのプランを使うとCLEARDB_DATABASE_URLという環境変数(例: mysql://xxxxxxxxxxxxxx:xxxxxxxx@us-xxxx-xxxx-xxxx-xx.cleardb.net/heroku_xxxxxxxxxxxxxx?reconnect=true)が作成されるので、これをDATABASE_URLにコピーしてスキームのmysqlをmysql2に修正するだけで簡単に設定できる。

これをこのまま使うと、パラメータのreconnect=trueもdatabase.ymlに設定されてしまうので注意が必要。

Amazon LightsailのWordPressのphpMyAdminに接続する

LightsailのwordpressにはphpMyAdminがインストールされていますが、デフォルトではローカルホスト以外からの接続は拒否されてしまいます。SSHポートフォワーディングを使うことで安全にphpMyAdminに接続することができます。

ssh [HOST] -L 8080:localhost:80 -N

あとはブラウザで http://localhost:8080/phpmyadmin でphpMyAdminにアクセスできます。

ログインアカウント名は root、パスワードはホームディレクトリの bitnami_application_password です。

Heroku Postgres のデータベースをローカルの開発環境にリストアする

Herokuの本番環境のデータベースをローカル環境にコピーして利用したい場合の手順。

データベースのバックアップを作成

heroku pg:backups capture --app app_name

コマンドを実行するとバックアップが実行される。しばらくしてバックアップが終了すると以下のように表示されるので、バックアップ名(b001の部分)を控えておく。

Backing up DATABASE to b001... done

バックアップをローカルにダウンロード

heroku pg:backups:download b001 --app app_name

先ほど控えておいたバックアップ名を指定してダウンロードする。カレントディレクトリに latest.dump という名前でダンプファイルが作成される。

データベースのリストア

pg_restore --verbose --clean --no-acl --no-owner -h localhost -U user_name -d database_name latest.dump

S3の特定のプレフィックスのオブジェクトをいっぺんに消す

アクセスログのプレフィックスを logs/ と間違えて logs としてしまい、ルートディレクトリに logs2020-03-19-01-40-54-C990FDCF5A1EE0AA みたいなファイルがたくさんできてしまったので削除したかった。

aws --profile profile-name s3 rm s3://bucket-name/ --exclude '*' --include 'logs*'

--dryrun オプションをつけると dry run できる。

aws --profile profile-name s3 rm s3://bucket-name/ --exclude '*' --include 'logs*' --dryrun

RailsでNOT NULL制約をマイグレーションでつける

Railsで、NOT NULL制約がついてないカラムに後からマイグレーションでNOT NULL制約をつける時のやり方。

migrateファイルで、change_column_nullを使う。DEFAULTも設定する場合はさらにchange_column_defaultも行う必要がある。

class ExampleMigration < ActiveRecord::Migration[6.0]
  def change
    change_column_null :table, :column, false, true
    change_column_default :table, :column, from: nil, to: true
  end
end

change_column を使うと PG::NotNullViolation: ERROR: column "column" contains null values の様に、すでにレコードが作成されていた場合はエラーになってしまう。change_column_nullを使うとNULLのカラムをデフォルト値(4パラ目)でUPDATEしてからNOT NULL制約をつけてくれる。

Railsで特定のコントローラーでセッションを使わないようにする

Railsはコントローラーで session に書き込みを行うとセッションIDがアサインされ、Set-CookieでCookieにセッションIDが設定される。

デフォルトでは全てのリクエストでCSRFトークンをセッションに格納しているため、何も設定していないとランディングページなどのセッションをあまり必要としない静的ページへのアクセスでセッションストアの容量が圧迫されたりしてしまう。

コントローラーで protect_against_forgery? をオーバーライドして false を返すようにすると、session に書き込みが行われないため、新規にセッションIDがアサインされなくなる。

class StaticPagesController < ApplicationController
  skip_before_action :authenticate_user!

  parivate

  def protect_against_forgery?
    false
  end
end

ただし当然ながらCSRFトークンが作成されなくなるため、使いどころは注意されたし。

外部サービスで使用しているPostgresqlのデータベースをHeroku Postgresにリストアする

基本的にはHerokuのドキュメントに全て書いてある。
https://devcenter.heroku.com/articles/heroku-postgres-backups

今回はAWS EC2のRailsアプリケーションをHerokuに移行した時のデータベースのコピーしたので、手順をメモしておく。

AWSサービス側での操作

  1. メンテナンス画面にした後、冗長化してあるWEBサーバーを止めて1台のシングル構成に。
  2. パブリックディレクトリ(Herokuがアクセスできる場所)にPostgresqlのダンプファイルを作成する。念のため、ファイル名は乱数にでもしておく。
PGPASSWORD=$PG_PASSWORD pg_dump -Fc --no-acl --no-owner -U $PG_USER -h $PG_HOST -p $PG_PORT $PG_DATABASE -f /var/www/app/current/public/xxxxxxxxxx.dump

Heroku側での操作

heroku pg:backups:restore 'https://www.app.com/xxxxxxxxxx.dump' DATABASE_URL --app=app-name --confirm=app-name

これでHerokuにDBがコピーされるので、ドメインをHerokuに向けてメンテナンスを解除する。

注意

heroku pg:backups:restore を実行すると、URLにアクセスできなかったなどの理由でリストアに失敗した場合でもHeroku Postgres のデータベースは削除されてしまう。

Railsコンソールで手っ取り早くバリデーションの動作確認をするワンライナー

->(c, k, v) { c.new(k => v).tap(&:valid?).errors[k] }.call(User, :email, "text@example.com")

ポイント

  • tap内 で valid? を実行することでメソッドチェーンで errors が呼び出せる。
  • ラムダ式を使って変数がコードの後ろに来るようにしてあるので、コンソール内で値を変えながら何度も動かしてみるのが楽。