カテゴリー: 未分類

自己署名証明書を生成してくれるdockerコンテナOMGWTFSSLを試す

ローカルでの開発などでLet’s Encryptを使用できないときに、従来の方法で自己署名証明書が必要な際、このOMGWTFSSLを使って証明書を生成すると、プライベート認証局の証明書とそれで署名したサーバ証明書を得ることができます。

プライベート認証局の証明書をブラウザに登録し、サーバ証明書をApache,NGIXなどに設定すると、例外設定せずにhttpsでアクセスすることができます。

paulczar/omgwtfssl: SSL certificate generation for developers who don’t TLS good

OpenSSLを使った従来の方法

OMGWTFSSLを使った方法

前提

  • OSはUbuntu 18.04
  • WEBサーバとしてApacheを使用
  • Dockerはインストール済み
  • foo.example.jpというドメイン名でアクセスできるように設定済み

証明書の生成とインストール

  1. OMGWTFSSLコンテナを実行
    $ docker run -e SSL_SUBJECT="foo.example.jp" -v /tmp/certs:/certs  paulczar/omgwtfssl
    ----------------------------
    | OMGWTFSSL Cert Generator |
    ----------------------------
    
    --> Certificate Authority
    ====> Generating new CA key ca-key.pem
    Generating RSA private key, 2048 bit long modulus
    ....................................................+++
    .+++
    e is 65537 (0x10001)
    ====> Generating new CA Certificate ca.pem
    ====> Generating new config file openssl.cnf
    ====> Generating new SSL KEY key.pem
    Generating RSA private key, 2048 bit long modulus
    ....................................................................................................................................................................................................................+++
    ....................................................+++
    e is 65537 (0x10001)
    ====> Generating new SSL CSR key.csr
    ====> Generating new SSL CERT cert.pem
    Signature ok
    subject=/CN=foo.example.jp
    Getting CA Private Key
    ====> Complete
    keys can be found in volume mapped to /certs
    
    ====> Output results as YAML
    ---
    ca_key: |
      -----BEGIN RSA PRIVATE KEY-----
      :
      :
      :
      -----END RSA PRIVATE KEY-----
    
    ca_crt: |
      -----BEGIN CERTIFICATE-----
      :
      :
      :
      -----END CERTIFICATE-----
    
    ssl_key: |
      -----BEGIN RSA PRIVATE KEY-----
      :
      :
      :
      -----END RSA PRIVATE KEY-----
    
    ssl_csr: |
      -----BEGIN CERTIFICATE REQUEST-----
      :
      :
      :
      -----END CERTIFICATE REQUEST-----
    
    ssl_crt: |
      -----BEGIN CERTIFICATE-----
      :
      :
      :
      -----END CERTIFICATE-----
    
  2. 生成されたファイルの確認
    $ ls -l /tmp/certs
    total 32
    -rw-r--r-- 1 root root 1679 Apr 15 07:51 ca-key.pem
    -rw-r--r-- 1 root root  973 Apr 15 07:51 ca.pem
    -rw-r--r-- 1 root root   17 Apr 15 07:51 ca.srl
    -rw-r--r-- 1 root root 1066 Apr 15 07:51 cert.pem
    -rw-r--r-- 1 root root  997 Apr 15 07:51 key.csr
    -rw-r--r-- 1 root root 1675 Apr 15 07:51 key.pem
    -rw-r--r-- 1 root root  241 Apr 15 07:51 openssl.cnf
    -rw-r--r-- 1 root root 3791 Apr 15 07:51 secret.yaml
    

    プライベート認証局の証明書と秘密鍵、サーバ証明書とその秘密鍵などが生成されている

  3. サーバ証明書を移動

    ApacheのデフォルトSSL設定の/etc/apache2/sites-available/default-ssl.confにある、SSLCertificateFileSSLCertificateKeyFileのパスがそれぞれ、/etc/ssl/certs//etc/ssl/private/にあるので、それにならってファイルを移動

    $ sudo mv /tmp/certs/cert.pem /etc/ssl/certs/
    $ sudo mv /tmp/certs/key.pem /etc/ssl/private/
    
  4. サイトの追加

    Apacheにfoo.example.jp用の設定を追加する

    $ sudo vi /etc/apache2/sites-available/999-foo.conf
    
    <VirtualHost *:443>
        ServerName foo.example.jp
    
        DocumentRoot /var/www/html
    
        SSLEngine On
        SSLCertificateFile      /etc/ssl/certs/cert.pem
        SSLCertificateKeyFile   /etc/ssl/private/key.pem
    </VirtualHost>
    

    必要に応じてSSLOptionsなども追加する

  5. ApacheのSSLモジュール有効化

    $ sudo a2enmod ssl
    
  6. サイト設定を有効化
    $ sudo a2ensite 999-foo
    
  7. Apache再起動
    $ sudo systemctl restart apache2
    

ブラウザに認証局証明書のインストール

https://foo.example.jp にアクセスすると、証明書の発行元不明エラーが出るのでブラウザに認証局証明書をインストールする

  • Firefox
    firefoxでfoo.example.jpにアクセス
    SSL警告内容詳細
  • Chrome
    chromeでfoo.example.jpにアクセス

Firefoxの場合

  1. Firefoxオプションを開く

    オプション→プライバシーとセキュリティー→証明書

    firefox証明書オプション

  2. 証明書マネージャーを開く

    証明書を表示ボタンを押下して証明書マネージャーを開く

    firefox証明書マネージャー

  3. 認証局証明書をインポート

    1. 認証局証明書タブを選択して、その下のインポートボタンを押下

    2. /tmp/certs/ca.pemをダウンロードやファイル移動などで取得し、それを選択

    3. 証明書のインポートダイアログが表示されるので、この認証局によるウェブサイトの識別を信頼するにチェックしてOKボタンを押下

      認証局証明書のインポート

    正常にインポートできていれば、認証局証明書のリストにtest-caが追加されている

    認証局証明書のインポート後

  4. 再度Firefoxで https://foo.example.jp にアクセス

    認証局証明書のインストール後

Chrome(Windows)の場合

Windows版のChromeはインターネットオプションにある証明書を使用しているため、Chromeの設定から開く方法と、コントロールパネルから開く方法がある

  1. 証明書のインポートウィザートでインポートする証明書を選択する

    その際、デフォルトの拡張子がX.509証明書(*.cer, *.crt)となっていることがあるため、拡張子がpemのca.pemが表示されない

    ファイル名横のリストをすべてのファイル(*.*)に変更することで選択可能になる

    証明書インポートウィザード1

  2. インポートする先(証明書ストア)は信頼されたルート証明機関を選択する

    証明書インポートウィザード2

  3. セキュリティ警告ダイアログが表示されるのでOKを押下

  4. 正常にインポートできていれば、信頼されたルート証明機関のリストにtest-caが追加されている

    Chromeでルート証明書インポート後

  5. https://foo.example.jp にChromeでアクセス

    Chromeでルート証明書インストール後

    Firefoxと違ってエラー(NET::ERR_CERT_COMMON_NAME_INVALID)が表示されたまま

    Chrome58で、HTTPSの自己証明書が NET::ERR_CERT_COMMON_NAME_INVALID になる場合の対応より、サーバ証明書にX509v3 Subject Alternative Nameを含むようにしないといけない

  6. オプションを追加してサーバ証明書を再度生成する

    $ docker run -e SSL_SUBJECT="foo.example.jp" -e SSL_DNS="foo.example.jp" -v /tmp/certs:/certs  paulczar/omgwtfssl
    ----------------------------
    | OMGWTFSSL Cert Generator |
    ----------------------------
    
    --> Certificate Authority
    ====> Using existing CA Key ca-key.pem
    ====> Using existing CA Certificate ca.pem
    ====> Generating new config file openssl.cnf
    ====> Generating new SSL KEY key.pem
    Generating RSA private key, 2048 bit long modulus
    .........................................................+++
    ...................................................+++
    e is 65537 (0x10001)
    ====> Generating new SSL CSR key.csr
    ====> Generating new SSL CERT cert.pem
    Signature ok
    subject=/CN=foo.example.jp
    Getting CA Private Key
    ====> Complete
    keys can be found in volume mapped to /certs
    
    ====> Output results as YAML
    ---
    ca_key: |
      -----BEGIN RSA PRIVATE KEY-----
       :
       :
      -----END RSA PRIVATE KEY-----
    
    ca_crt: |
      -----BEGIN CERTIFICATE-----
       :
       :
       :
      -----END CERTIFICATE-----
    
    ssl_key: |
      -----BEGIN RSA PRIVATE KEY-----
       :
       :
       :
      -----END RSA PRIVATE KEY-----
    
    ssl_csr: |
      -----BEGIN CERTIFICATE REQUEST-----
       :
       :
       :
      -----END CERTIFICATE REQUEST-----
    
    ssl_crt: |
      -----BEGIN CERTIFICATE-----
       :
       :
       :
      -----END CERTIFICATE-----
    

    生成されたサーバ証明書を確認する

    $ openssl x509 -in /tmp/certs/cert.pem -text
    Certificate:
         :
         :
         :
            Issuer: CN = test-ca
         :
         :
         :
            Subject: CN = foo.example.jp
         :
         :
         :
            X509v3 extensions:
                X509v3 Basic Constraints:
                    CA:FALSE
                X509v3 Key Usage:
                    Digital Signature, Non Repudiation, Key Encipherment
                X509v3 Extended Key Usage:
                    TLS Web Client Authentication, TLS Web Server Authentication
                X509v3 Subject Alternative Name:
                    DNS:foo.example.jp, DNS:foo.example.jp
         :
         :
         :
    

    ※ paulczar/omgwtfsslが使用しているベースコンテナのalpineの仕様変更のためか、SSL_DNSオプションを追加しても「X509v3 Subject Alternative Name」が出力されなくなっています。paulczar/omgwtfsslからフォークされたstakater/ssl-certs-generator:1.0を使用すると出力されました(2019/05/09)

    $ docker run -e SSL_SUBJECT="foo.example.jp" -e SSL_DNS="foo.example.jp" -v /tmp/certs:/certs stakater/ssl-certs-generator:1.0
    
  7. 認証局の証明書と鍵が生成済みの場合、サーバ証明書への署名はそれを利用するので認証局証明書は再度インポートする必要はない
    ====> Using existing CA Key ca-key.pem
    ====> Using existing CA Certificate ca.pem
    
  8. 生成したサーバ証明書を上書きする
    $ sudo cp /tmp/certs/cert.pem /etc/ssl/certs/
    $ sudo cp /tmp/certs/key.pem /etc/ssl/private/
    $ sudo systemctl reload apache2
    
  9. Chromeでアクセスして確認

    証明書更新後にChromeでアクセス

広告

Firefox SendをDockerで動かす

前提

  • OSはUbuntu 18.04
  • docker, docker-compose
  • サーバにホスト名send.example.jpでアクセスできるように設定済み

Dockerで動かす

  1. 設置先を作成
    $ sudo mkdir -p /var/www/firefox-send
    $ sudo chown $USER /var/www/firefox-send
    
  2. データ保存フォルダを作成
    $ mkdir /var/www/firefox-send/data
    $ chmod 777 /var/www/firefox-send/data
    
  3. Firefox Sendのコードをクローン
    $ cd /var/www/firefox-send
    $ git clone https://github.com/mozilla/send.git
    
  4. 最新版(記事時点で3.0.9)のタグに切り替える
    $ cd send
    $ git checkout refs/tags/v3.0.9
    
  5. Firefox Sendのマニュアルに従いセットアップ
    $ npm install
    $ npm run build
    
  6. docker-compose.yml編集
    • seleniumは不要なので削除
      @@ -10,10 +10,3 @@
             - REDIS_HOST=redis
         redis:
           image: redis:alpine
      -  selenium-firefox:
      -    image: b4handjr/selenium-firefox
      -    ports:
      -      - "${VNC_PORT:-5900}:5900"
      -    shm_size: 2g
      -    volumes:
      -      - .:/code
      
    • server/config.jsを参考に、最大ファイルサイズ(デフォルト1G)、最大ダウンロード可能回数(デフォルト5回)、最大ダウンロード有効期限(デフォルト1日)を
      それぞれ2G, 100回, 604800秒(7日)に変更する

      @@ -8,5 +8,8 @@
             - "1443:1443"
           environment:
             - REDIS_HOST=redis
      +      - ANON_MAX_FILE_SIZE=2147483648
      +      - ANON_MAX_DOWNLOADS=100
      +      - ANON_MAX_EXPIRE_SECONDS=604800
         redis:
           image: redis:alpine
      
    • アップロードされたファイルの保存先はデフォルトではos.tmpdir()とランダム文字列のフォルダ名で作成されるため、マウントできるように固定化し、ホストと接続する
      @@ -11,5 +11,8 @@
             - ANON_MAX_FILE_SIZE=2147483648
             - ANON_MAX_DOWNLOADS=100
             - ANON_MAX_EXPIRE_SECONDS=604800
      +      - FILE_DIR=/tmp/send
      +    volumes:
      +      - ../data:/tmp/send
         redis:
           image: redis:alpine
      

    最終形

    version: "3"
    services:
      web:
        build: .
        links:
          - redis
        ports:
          - "1443:1443"
        environment:
          - REDIS_HOST=redis
          - ANON_MAX_FILE_SIZE=2147483648
          - ANON_MAX_DOWNLOADS=100
          - ANON_MAX_EXPIRE_SECONDS=604800
          - FILE_DIR=/tmp/send
        volumes:
          - ../data:/tmp/send
      redis:
        image: redis:alpine
    
  7. コンテナ起動

    初回はイメージのダウンロード、イメージのビルドが行われたのち、起動する。

    $ docker-compose up
    Creating network "send_default" with the default driver
    Pulling redis (redis:alpine)...
    :
    :
    :
    Building web
    :
    :
    :
    Successfully built 6b7d96723980
    Successfully tagged send_web:latest
    WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
    Creating send_redis_1 ... done
    Creating send_web_1   ... done
    Attaching to send_redis_1, send_web_1
    redis_1  | 1:C 12 Apr 2019 06:19:49.928 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    redis_1  | 1:C 12 Apr 2019 06:19:49.929 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
    redis_1  | 1:C 12 Apr 2019 06:19:49.929 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
    redis_1  | 1:M 12 Apr 2019 06:19:49.931 * Running mode=standalone, port=6379.
    redis_1  | 1:M 12 Apr 2019 06:19:49.931 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
    redis_1  | 1:M 12 Apr 2019 06:19:49.931 # Server initialized
    redis_1  | 1:M 12 Apr 2019 06:19:49.931 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
    redis_1  | 1:M 12 Apr 2019 06:19:49.931 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
    redis_1  | 1:M 12 Apr 2019 06:19:49.931 * Ready to accept connections
    

    正常起動が確認できれば、-dオプションをつけてバックグランド起動する。

  8. http://send.example.jp:1443 でアクセス確認

    Topページ

    1. ファイルのアップロードを確認

      セット
      UP中
      UP完了

    2. ファイルが保存されているのを確認

      $ ls -hl /var/www/firefox-send/data/
      total 101M
      -rw-r--r-- 1 10001 10001 101M Apr 12 07:04 1-cf9812b3fc33ef68
      
    3. ダウンロード確認

      UP後Top
      DL
      DL中
      DL後

Apacheのプロキシ連携

http://send.example.jp:1443 でアクセスしているのを、 http://send.example.jp でアクセスするためにApacheを使用する。

Apacheはインストール済みとする。(apt install apache2)

プロキシ設定は、node.js – WebSockets and Apache proxy : how to configure mod_proxy_wstunnel? – Stack Overflowを参考にした。

  1. サイト設定ファイルを追加
    $ sudo vi /etc/apache2/sites-available/999-send.conf
    

    内容

    <VirtualHost *:80>
        ServerName send.example.jp
    
        ProxyRequests Off
        ProxyVia Off
        ProxyPreserveHost On
    
        <Proxy *>
             Require all granted
        </Proxy>
    
        RewriteEngine On
    
        # websocket
        RewriteCond %{HTTP:Upgrade}  =websocket                     [NC]
        RewriteRule ^/api/ws(.*)     ws://localhost:1443/api/ws$1   [P,L]
    
        # rest
        ProxyPass /api http://localhost:1443/api
        ProxyPassReverse /api http://localhost:1443/api
    
        # static content
        ProxyPass / http://localhost:1443/
        ProxyPassReverse / http://localhost:1443/
    </VirtualHost>
    
  2. 必要なApacheモジュールの有効化(mod_rewrite,mod_proxy,mod_proxy_http,mod_proxy_wstunnel)
    $ sudo a2enmod rewrite proxy proxy_http proxy_wstunnel
    Enabling module rewrite.
    Enabling module proxy.
    Considering dependency proxy for proxy_http:
    Module proxy already enabled
    Enabling module proxy_http.
    Considering dependency proxy for proxy_wstunnel:
    Module proxy already enabled
    Enabling module proxy_wstunnel.
    To activate the new configuration, you need to run:
      systemctl restart apache2
    
  3. サイトの有効化
    $ sudo a2ensite 999-send
    Enabling site 999-send.
    To activate the new configuration, you need to run:
      systemctl reload apache2
    
  4. Apache再起動
    $ sudo systemctl restart apache2
    $ sudo systemctl status apache2
    ● apache2.service - The Apache HTTP Server
       Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
      Drop-In: /lib/systemd/system/apache2.service.d
               └─apache2-systemd.conf
       Active: active (running) since Fri 2019-04-12 07:22:40 UTC; 6s ago
      Process: 8870 ExecStop=/usr/sbin/apachectl stop (code=exited, status=0/SUCCESS)
      Process: 8876 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
     Main PID: 8892 (apache2)
        Tasks: 55 (limit: 4703)
       CGroup: /system.slice/apache2.service
               ├─8892 /usr/sbin/apache2 -k start
               ├─8893 /usr/sbin/apache2 -k start
               └─8894 /usr/sbin/apache2 -k start
    
    Apr 12 07:22:40 firefoxsend systemd[1]: Starting The Apache HTTP Server...
    Apr 12 07:22:40 firefoxsend systemd[1]: Started The Apache HTTP Server.
    
  5. http://send.example.jp でアクセスして確認

    HTTPで接続

SSL

実際に使う場合にはSSLを使用する必要がある。

docker-compose.ymlにNODE_ENV=productionを追加すると、./server/routes/upload.js, ./server/routes/ws.jsにある

const protocol = config.env === 'production' ? 'https' : req.protocol;
const url = `${protocol}://${req.get('host')}/download/${newId}/`;

において、ファイルのダウンロードURLのプロトコル部分がhttpsになる。

また、大きなファイルをアップロードしてhttpでアクセスすると「このブラウザーは、この大きさのファイルを復号化できません。」と表示されてしまう。
HTTP接続で1Gファイルをダウンロード

一方でhttpsで接続すると、問題なくダウンロードできる。
HTTPS接続で1Gファイルをダウンロード

設定サンプル

a2ensite default-ssl
a2enmod ssl

また999-send.confを以下のように変更する。(ポート番号の変更、証明書の指定)

<VirtualHost *:443>
    ServerName send.example.jp

    SSLEngine on
    SSLCertificateFile      /~~~/server.pem
    SSLCertificateKeyFile   /~~~/serverkey.pem

    ProxyRequests Off
    ProxyVia Off
    ProxyPreserveHost On

    <Proxy *>
         Require all granted
    </Proxy>

    RewriteEngine On

    # websocket
    RewriteCond %{HTTP:Upgrade}  =websocket                     [NC]
    RewriteRule ^/api/ws(.*)     ws://localhost:1443/api/ws$1   [P,L]

    # rest
    ProxyPass /api http://localhost:1443/api
    ProxyPassReverse /api http://localhost:1443/api

    # static content
    ProxyPass / http://localhost:1443/
    ProxyPassReverse / http://localhost:1443/

</VirtualHost>

MinIOとの連携

Firefox Sendは保存先にS3が使用できる。そこで、S3互換のオブジェクトストレージのMinIOを保存先として使用してみる。

MinIOもDockerコンテナが提供されているのでそれを使用する。

  1. MinIOの起動
    1. MinIO保存先フォルダを作成
    $ mkdir /var/www/firefox-send/minio
    $ chmod 777 /var/www/firefox-send/minio
    
    1. MinIOコンテナ起動
    $ cd /var/www/firefox-send
    $ docker run -p 9000:9000 -v $(pwd)/minio:/data -e "MINIO_ACCESS_KEY=MinIO" -e "MINIO_SECRET_KEY=MinIO123" minio/minio server /data
    

    MINIO_ACCESS_KEY,MINIO_SECRET_KEYは適当なものに変更する

    1. ブラウザで http://send.example.jp:9000 にアクセス

    MinIOにアクセス

    1. MINIO_ACCESS_KEY,MINIO_SECRET_KEYでログイン

    MinIOログイン後

    1. バケットの作成

    右下の+ボタンを押下してCreate bucketを選択し、適当なバケット名で作成する。ここではsendという名前を使用する。

    バケット作成
    バケット作成2
    バケット作成3

    1. ファイルのアップロード

    右下の+ボタンを押下してUpload fileを選択し、適当なファイルをアップロードする

    MinIOへファイルアップロード

    1. アップロードファイルの確認
    $ ls -al /var/www/firefox-send/minio
    total 16
    drwxrwxrwx 4 vagrant vagrant 4096 Apr 12 10:24 .
    drwxr-xr-x 5 vagrant root    4096 Apr 12 10:00 ..
    drwxr-xr-x 6 root    root    4096 Apr 12 10:24 .minio.sys
    drwxr-xr-x 2 root    root    4096 Apr 12 10:24 send
    
    $ ls -al /var/www/firefox-send/minio/send
    total 102408
    drwxr-xr-x 2 root    root         4096 Apr 12 10:24 .
    drwxrwxrwx 4 vagrant vagrant      4096 Apr 12 10:24 ..
    -rw-r--r-- 1 root    root    104857600 Apr 12 10:24 test_100M
    
  2. Firefox Sendと連携
    1. server/storage/s3.jsの編集

      Firefox SendでS3を使用する際、設定ファイルに書くのはS3のバケット名のみ。このままだとAWSに接続してしまうため、エンドポイントも指定できるようにコードを変更する。

      参考

      @@ -1,4 +1,15 @@
       const AWS = require('aws-sdk');
      +const config = {};
      +if (typeof process.env.AWS_S3_ENDPOINT !== 'undefined') {
      +  config['endpoint'] = process.env.AWS_S3_ENDPOINT;
      +}
      +if (typeof process.env.AWS_S3_USE_PATH_STYLE_ENDPOINT !== 'undefined') {
      +  config['s3ForcePathStyle'] = process.env.AWS_S3_USE_PATH_STYLE_ENDPOINT == 'true' ? true : false;
      +}
      +if (typeof process.env.AWS_S3_SIGNATURE_VERSION !== 'undefined') {
      +  config['signatureVersion'] = process.env.AWS_S3_SIGNATURE_VERSION;
      +}
      +AWS.config.update(config);
       const s3 = new AWS.S3();
      
       class S3Storage {
      
    2. docker-compose.ymlにMinIO接続設定を追加

      s3.jsへの変更で追加した、AWS_S3_ENDPOINT, AWS_S3_USE_PATH_STYLE_ENDPOINT,AWS_S3_SIGNATURE_VERSIONに加え、MinIOの認証情報(MINIO_ACCESS_KEY, MINIO_SECRET_KEY)をaws-sdkが認識する環境変数(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)を使ってセットする。

      @@ -11,8 +11,13 @@
             - ANON_MAX_FILE_SIZE=2147483648
             - ANON_MAX_DOWNLOADS=100
             - ANON_MAX_EXPIRE_SECONDS=604800
      -      - FILE_DIR=/tmp/send
             - NODE_ENV=production
      +      - S3_BUCKET=send
      +      - AWS_ACCESS_KEY_ID=MinIO
      +      - AWS_SECRET_ACCESS_KEY=MinIO123
      +      - AWS_S3_ENDPOINT=http://172.17.0.1:9000
      +      - AWS_S3_USE_PATH_STYLE_ENDPOINT=true
      +      - AWS_S3_SIGNATURE_VERSION=v4
           volumes:
             - ../data:/tmp/send
         redis:
      

      エンドポイントのホストはFirefox SendのWEBコンテナ(send_web_1)から見たMinIOコンテナ(hardcore_cray)になることに注意。localhostだとFirefox SendのWEBコンテナ自身を指すことになる。

      vagrant@firefoxsend:/var/www/firefox-send/send$ docker ps
      CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                    PORTS                    NAMES
      cd9ea929756e        send_web            "node server/bin/pro…"   7 minutes ago       Up 7 minutes              0.0.0.0:1443->1443/tcp   send_web_1
      b6a74fc54b0e        minio/minio         "/usr/bin/docker-ent…"   33 minutes ago      Up 33 minutes (healthy)   0.0.0.0:9000->9000/tcp   hardcore_cray
      b51bf27c6c54        redis:alpine        "docker-entrypoint.s…"   5 hours ago         Up 7 minutes              6379/tcp                 send_redis_1
      vagrant@firefoxsend:/var/www/firefox-send/send$ docker inspect hardcore_cray|grep Gateway
                  "Gateway": "172.17.0.1",
                  "IPv6Gateway": "",
                          "Gateway": "172.17.0.1",
                          "IPv6Gateway": "",
      

      MinIOコンテナのGatewayの値(172.17.0.1)を使用した。

    3. コンテナの再ビルド

      server/storage/s3.jsの変更をコンテナに反映するためビルドを行う

      docker-compose build
      
    4. コンテナ起動
      $ docker-compose restart
      Restarting send_web_1   ... done
      Restarting send_redis_1 ... done
      
    5. ファイルをアップロードしてMinIO側に保存されるか確認

      Send側
      MinIO側

      MinIO側の保存ディレクトリにファイルがあるか確認

      $ ls -lh /var/www/firefox-send/minio/send
      total 101M
      -rw-r--r-- 1 root root 101M Apr 15 06:35 1-ec820a4eb15f7917
      

      同じIDのファイルがアップロードされ、保存されている。

docker-composeに入れた版

ネットワークの指定が簡単になるのでMinIOもdocker-compose.ymlに入れてみた

参考
MinIO | Deploy MinIO on Docker Compose

version: "3"
services:
  web:
    build: .
    links:
      - redis
      - minio
    ports:
      - "1443:1443"
    environment:
      - REDIS_HOST=redis
      - ANON_MAX_FILE_SIZE=2147483648
      - ANON_MAX_DOWNLOADS=100
      - ANON_MAX_EXPIRE_SECONDS=604800
      - NODE_ENV=production
      - S3_BUCKET=send
      - AWS_ACCESS_KEY_ID=MinIO
      - AWS_SECRET_ACCESS_KEY=MinIO123
      - AWS_S3_ENDPOINT=http://minio:9000
      - AWS_S3_USE_PATH_STYLE_ENDPOINT=true
      - AWS_S3_SIGNATURE_VERSION=v4
  redis:
    image: redis:alpine
  minio:
    image: minio/minio
    ports:
      - "9000:9000"
    environment:
      - MINIO_ACCESS_KEY=MinIO
      - MINIO_SECRET_KEY=MinIO123
    volumes:
      - ../data:/data
    command: server /data

QNAP上のファイル名の文字化けを直す

文字コードをUTF8で運用しているQNAP NAS上に、文字コードがSJISの状態で日本語ファイル名のファイルがアップロードされたため、文字化けしたファイル名(フォルダ名)を修正する

準備

概要

文字化けを起こしたファイルのリネーム方法 – Qiitaに沿って修正します。

文字化け前のファイル名を知りたいため、iconvでのファイル名確認を追加しました。

  1. lsコマンドで対象ファイル(フォルダ)のinode番号を確認
  2. iconvコマンドで元のファイル名を確認
  3. findコマンドの-inumオプションで1で確認した番号でファイルを指定し、-execオプションを使いmvでリネーム

しかしQNAPのシェルでは、

  • iconvコマンドがない
  • findコマンドの-inumオプションない

という状況のため、解決法として、NASなどの組み込みデバイス向けソフトウェアリポジトリのEntwareを使い、findとiconvをインストールしそれを利用するようにします。

Entwareインストール

  1. EntwareのInstall on QNAP NASにアクセスし、this package for standard installationのリンクからQPKGファイルをダウンロード
  2. QNAPの管理画面を開く
  3. AppCenterを開き右上の歯車(設定)をクリック AppCenterを開いたとき
  4. 手動でインストールから参照を選択し、1でダウンロードしたQPKGファイルを指定する。インストールボタンを押下してインストール パッケージの手動インストール
  5. 正常にインストールするとマイアプリに表示される Entwareインストール後

findutilsとiconvをインストール

  1. QNAPにSSHで接続(文字コードはUTF-8)
  2. Entwareのパッケージ管理コマンドのopkgコマンドを使用してfindutilsとiconvをインストール
    [~] # opkg install findutils iconv
    

文字化け修正

  1. lsコマンドで対象ファイル(フォルダ)のinode番号を確認
        [/share/homes/sample] # ls -li
        50528266 lrwxrwxrwx    1 admin    administ        31 Jun  4 17:41 @Recycle -> /share/homes/@Recycle/sample/
        50528923 -rw-rw-rw-    1 sample   everyone       161 Jun  4 17:41 ??{??t?@?C????.txt
        

    文字化けファイル名のファイルのinode番号が50528923であることを確認

  2. iconvコマンドで元のファイル名を確認
        [/share/homes/sample] # ls -li|iconv -f SJIS -t UTF-8
        50528266 lrwxrwxrwx    1 admin    administ        31 Jun  4 17:41 @Recycle -> /share/homes/@Recycle/sample/
        50528923 -rw-rw-rw-    1 sample   everyone       161 Jun  4 17:41 日本語ファイル名.txt
        
  3. findコマンドの-inumオプションで1で確認した番号でファイルを指定し、-execオプションを使いmvでリネーム
            [/share/homes/sample] # find . -inum 50528923 -ok mv '{}' "日本語ファイル名.txt" \;
            < mv ... ./??{??t?@?C????.txt > ? y
        
  4. リネーム結果を確認
        [/share/homes/sample] # ls -li
        50528266 lrwxrwxrwx    1 admin    administ        31 Jun  4 17:41 @Recycle -> /share/homes/@Recycle/sample/
        50528923 -rw-rw-rw-    1 sample   everyone       161 Jun  4 17:41 日本語ファイル名.txt
        

リネームする対象が多いとき

  1. awkを使ってコマンド文字列を生成
    ls -il|iconv -f Shift_JIS -t UTF-8 |awk -v q=\'  '{print "yes\|find . -inum "$1" -ok mv "q"{}"q" "q$10q" \\;"}'
    

    出力結果

    yes|find . -inum 61801127 -ok mv '{}' '日本語ファイル名1.jpg' \;
    yes|find . -inum 61801128 -ok mv '{}' '日本語ファイル名2.jpg' \;
    yes|find . -inum 61801129 -ok mv '{}' '日本語ファイル名3.jpg' \;
    :
    :
    :
    :
    
  2. (生成されたコマンドに問題なければ)生成した文字列を実行していく

参考

package.jsonにあるversionを取得したい

コード中に自身のpackage.jsonにある値を取得するには、フィールド名の頭にnpm_package_をつけるて、process.envから参照できる。

バージョン番号(version)を取得したい場合:

console.log(process.env.npm_package_version);

パッケージで使う場合は、process.envは、読み込み元のpackage.jsonの値が使われるため、requireを使って直接package.jsonを読み込む。

p = require('package.json');
console.log(p.version);

Ubuntu 16.04でAndroid実機を接続

Ubuntu 16.04上でAndroidアプリ開発を行う中で、実機での動作を確認しようと思い、USBデバッグを有効にしたHuawei P8 liteをUSBで接続し、adb devicesを実行したところ、以下のようなレスポンスになった。

$ adb devices
List of devices attached
ARCxxxxxxxxxxxxx    no permissions (user in plugdev group; are your udev rules wrong?); see [http://developer.android.com/tools/device.html]

ハードウェア端末上でアプリを実行するを参照すると、udevにルールファイルを追加して、開発で使用する各種端末のUSB設定を追加する必要があるとのこと。

追加するルールは、udev – Android adb no permission – Ask Ubuntuの中にあったandroid-udev-rulesを使用してみた。

  1. udevルールの追加
    ~$ mkdir work
    ~$ cd work/
    ~/work$ git clone https://github.com/M0Rf30/android-udev-rules.git
    Cloning into 'android-udev-rules'...
    remote: Counting objects: 833, done.
    remote: Compressing objects: 100% (8/8), done.
    remote: Total 833 (delta 2), reused 1 (delta 0), pack-reused 825
    Receiving objects: 100% (833/833), 202.48 KiB | 285.00 KiB/s, done.
    Resolving deltas: 100% (324/324), done.
    Checking connectivity... done.
    ~/work$ cd android-udev-rules
    ~/work/android-udev-rules$ sudo cp -v 51-android.rules /etc/udev/rules.d/51-android.rules
    '51-android.rules' -> '/etc/udev/rules.d/51-android.rules'
    ~/work/android-udev-rules$ sudo chmod a+r /etc/udev/rules.d/51-android.rules
    
  2. グループの追加
    <br />~/work/android-udev-rules$ sudo groupadd adbusers
    ~/work/android-udev-rules$ sudo usermod -a -G adbusers $(whoami)
    

    ※今回は、android-udev-rulesの手順通り行ったが、ユーザーはplugdevグループに属しているので、51-android.rules中のGROUP="adbusers"GROUP="plugdev"に変更すれば、グループの追加は不要。

  3. udev再起動

    ~/work/android-udev-rules$ sudo udevadm control --reload-rules
    ~/work/android-udev-rules$ sudo service udev restart
    
  4. 実機接続

    USBで接続しているAndroid端末を一度外し、再度接続。Android Debug Bridge(adb)を再起動する。

    ~/work/android-udev-rules$ adb kill-server
    ~/work/android-udev-rules$ adb devices
    List of devices attached
    ARCxxxxxxxxxxxxx    device
    

PHPアプリケーションをHerokuにデプロイするときに”ERROR: Couldn’t parse ‘composer.lock’; it must be a valid lock”エラー

PHPアプリケーションをHerokuにデプロイしようと思い、

git push heroku master

としたところ

-----> PHP app detected
-----> Bootstrapping...
-----> Installing platform packages...
 ! ERROR: Couldn't parse 'composer.lock'; it must be a valid lock
  file generated by Composer. Run 'composer update', add/commit
  the change, then push again.
 ! Push rejected, failed to compile PHP app.
 ! Push failed

となりデプロイが失敗。

composer.lockは存在しており、指示通りcomposer updateをしてcomposer.jsoncomposer.lockを更新したうえでデプロイしても同じエラーが発生しました。

php – Heroku ERROR: Failed parsing composer.lock; it must be non-empty and valid JSON – Stack Overflow

より

composer self-updateでcomposer自体を更新し、composer updateしたうえで、デプロイすることでエラーが出なくなりデプロイできました。

phpMyAdminでDATETIME型が「BLOB」と表示される

  • PHP5.6
  • Apache 2.2
  • MySQL 5.6

をソースからビルドし

  • phpMyAdmin4.6.4

を設置・設定したうえで、DATETIME型を含むテーブルを作りデータを投入後、phpMyAdminから内容を確認すると、

DATETIME型がBlog表示

と表示されてしまいました。

MySQLコマンドでのSELECTやMySQL Workbenchを使って確認したところ、日付として表示されており問題がない状況。

調べたところ、

php – phpMyAdmin: Date Fields Display as BLOB – Stack Overflow

が見つかり、phpinfo()でPHPのMySQLモジュールに何が使われているのか確認したところ、mysqlモジュールが使われていました。
そこで、mysqliモジュールを使うようにビルドしなおしたところ、

DATETIME型が正常に表示

と正常に表示されるようになりました。