diadia

興味があることをやってみる。自分のメモを残しておきます。

IPにかかわるものについて

IPアドレスは普通REMOTE_ADDRという変数名で取得できる。

しかしロードバランサやプロキシを介した通信になると、REMOTE_ADDRがロードバランサ等のアドレスになる。多くのロードバランサ等では、HTTPのリクエストヘッダにX-Forwarded-Forフィールドを追加する。

 

REMOTE_ADDR...IPレイヤの情報

X-Forwarded-For...HTTPレイヤの情報

データ取得先が変わるので値(IP)の取得方法も変わる。

django用に.gitignoreを設ける

.gitignoreを設けないとどうなるのか?

まずソースコードgithub,bitbucketからクローンして手に入れる。そしてそのままmigrateするとコマンドが通らない。おそらくこれはmigrations以下の.pyファイルやキャッシュファイルが存在しているかと思われる。実際削除すると動くからそのへんが関係あるのでしょう。そういうわけで.gitignoreを設けることが必要になる。

大前提

gitignoreファイルの作成はまずローカルの環境で行わう。ここがはっきりと意識できていなかったため無駄な作業を多くしてしまった。

じゃあ.gitignoreファイルはプロジェクトのどこに配置するべきか?

gitignoreはどこに配置するべきか?このどこに配置するべきかは重要なのか?これについて情報を集めておきたい。

参考文献

https://qiita.com/anqooqie/items/110957797b3d5280c44f

gitignoreに記述するファイルはdjangoの場合何を書くべきか?

まずキャッシュファイル

django-allauthを使ってメールを送信を絡めてユーザ登録したい

前提

sendgridを使ったユーザー登録を実行

emailを送信するためにはsettings.pyをいじると送れることは知っておくこと。
ここの設定によってemailの送信を例えばgmailから送ったり、sendgridのようなメール配信サービスのAPIを利用して送ったり、またはメールをターミナルに送信して確認することができる。

情報収集

まず本家のドキュメントを見ると,

ACCOUNT_EMAIL_REQUIRED (=False) The user is required to hand over an e-mail address when signing up. ACCOUNT_EMAIL_VERIFICATION (=”optional”) Determines the e-mail verification method during signup – choose one of "mandatory", "optional", or "none". When set to “mandatory” the user is blocked from logging in until the email address is verified. Choose “optional” or “none” to allow logins with an unverified e-mail address. In case of “optional”, the e-mail verification mail is still sent, whereas in case of “none” no e-mail verification mails are sent.

ACCOUNT_EMAIL_REQUIREDをTrueにする事が必要そうだ。
次にACCOUNT_EMAIL_VERIFICATIONには、値としてoptional,mandatory,noneがある。メール受信できたかどうか知りたいのでmandatoryにすれば良いと思われる。

気になること

sendgridを使ってメールを送信するのでユーザー登録時(sign up時)のviews.pyにsend_mail関数を付け加える必要があるのか無いのか?django-allauthのviewsの仕組みを理解する必要がある。

結論

django-allauthにメール送信機能も備え付けてあるため、自分でsend_mail関数を使って送信する必要がない。単純にsettings.pyにmail受信の確認設定さえすれば良い。

sendgridに関わるメモ

メモ

さくらVPSからsendgridを使うとお得。
https://vps-news.sakura.ad.jp/sendgrid1/

https://simpleit.rocks/python/django/adding-email-to-django-the-easiest-way/

上記リンクについて補足 
djangoのメール送信はsend_mailで送信できるが、sendgridを使う場合当該ライブラリをインストールしてsettings.pyを指定の通りに変更するだけでsendgridからメールを送信する状態に切り替えることができる。

どうやってメモ本文をhtml形式にして表示させることができるのか

 

ホワイトリストとは

https://salt.iajapan.org/wpmu/anti_spam/universal/measure/whitelist-blacklist/
メール受信の選別基準のようだ。受信するか否かの判断をブラックリスト,ホワイトリストで定めるようだ。ホワイトリストは指定した人からのみメールを受信する構造でブラックリストは指定された人からのメールは受信しないようにする構造らしい。

 

メールの見出し字大きさ指定とかしたい場合

まずdjangoにはメール送信に関わるスクリプトが準備してある。メールを送信するならsend_mail()関数を利用すれば良い。djangoのsend_mail()関数の引数の本文は文字列なので、いろいろ細工したいときには不都合だと感じた。
そこでいかなる方法を取れば単なる文字列から細工した状態に、もっと欲を言えば、htmlを反映したメール本文を表示できるか調べてみる。

考えられる方法として引数にhtmlファイルを渡すという方法が考えられる。方法としてsendgridにテンプレートを作り、それを送信する。引数にjsonのデータを使うことでテンプレート内容も編集可能のようだ。下記参照。

https://qiita.com/kikutaro/items/6513acd7420ee88839e9

その他の方法としてrender_to_string関数を用いるとテンプレートにカスタマイズできるようだ。下記参照
https://narito.ninja/blog/detail/64/
https://docs.djangoproject.com/ja/2.2/topics/templates/#django.template.loader.render_to_string

from django.template.loader import render_to_string
from django.core.mail import send_mail

subject = "件名"
context = dict()
context["client_name"] = client.name
context["orderId"] = orderId
template = "orders/mails/order_cofirm.txt"
message  = render_to_string(template,context)
recipient_list = []
recipient_list.append(client.email)
send_mail(subject, message, from_email, recipient_list)

変数templateはdjangoでテンプレートを指定するやり方で指定する。これはrender_to_strung関数の動きがテンプレート探索の方法をとっているからだ。つまり上記の変数templateを定めるならばorder_confirm.txtのパスは以下になる。project/orders/templates/orders/mails/order_confirm.txt

 

sendgridで改行コード"¥n"を使いたい

https://stackoverflow.com/questions/38158192/unable-to-get-a-single-linebreak-while-sending-email-through-sendgrid/38159026

上記によるとsendgridの仕様による影響で改行コードが反映されていないようだ。これについては以下を見るともっと分かりやすい。

https://qiita.com/Sekky0905/items/955a73e51ceb1671d4af

sendgridの仕様では、string型の文字列からhtmlに変換したものをメールとして配信するようだ。
”””Turn on if you don't want to convert your plain text email to HTML”””settings/mail settings/ plain content参照。 自分の設定もoffになっていたのでonにして試してみる。試した結果無事に改行が反映された文面でメールを送ることができました。

windowsでpython のgoogletransをインストールする方法

googletransはエラーが出る

よく考えられるpip installでgoogletransをインストールするとエラーが出て使えない状況に陥る。この状況にはパッチされた新たなgoogletransをインストールすることで解決できる。

環境

  • windows10
  • anaconda

やり方

https://stackoverflow.com/questions/52455774/googletrans-stopped-working-with-error-nonetype-object-has-no-attribute-group
上記のanswer通りgit cloneすればよい。しかしながらwindowsではmacとは違いgitはインストールされていない。したがってgitコマンドが存在しない。

そのためgit for windowsを使う方法も考えられるが、以下のようにして対処した。以下の方法はgitが全く分からなくても何しているか想像できる。

パッチされた新たなgoogletransのソースコードgithubから取得する。https://github.com/BoseCorp/py-googletrans

上記urlからclone or downloadボタンからソースコードをダウンロードする。

次にコマンドプロンプトを開き、googletransがあるディレクトリに移動する。

# 例えばデスクトップにグーグルトランスをダウンロードしたなら
C:\Users\USER\Desktop>cd py-googletrans

そして以下のコマンドを入力する。

pip install setup.py

これでグーグルトランスを使えるようになりました。

セキュリティ

不正アクセスの種類

ほとんどの不正アクセスSSH,FTP,HTTP/HTTPSであるらしい。セキュリティを上げるためにはこれらの設定を整えれば良いらしい。

httpに関しては海外IPアドレスからのアクセスを遮断する方法が有効であるらしい。

参考:https://www.cyberbrain.co.jp/news/security/01/
参考:https://www.seohacks.net/basic/terms/htaccess/
上の参考資料によると、http,httpsのアクセスは.htaccessで制限できるようだ。ただしこれはapacheでの使用を前提にしている記事を読んだので、nginxで.htaccessを使用できるかは不明である。

apache.htaccessをnginx用に変換するサービスが有るようだ。下記参照
https://teratail.com/questions/7098

nginxでは一般的にどのようにしてIP制限をするのだろうか

こちらを参考すると/etc/nginx/conf.d/project.confの設定ファイルを編集するだけでIP の制限ができるようだ。
https://qiita.com/ShinyaOkazawa/items/50b6ba4dcc8cb116ca91

allowにアクセスを許可するIPアドレスを記入する。deny allで全てを拒否する設定になる。

注意点

ipにはグローバルIPとプライベートIPが存在している。nginxの設定ファイルで必要としているIPはグローバルIPだ。プライベートIPはローカルのマシンから調べることができるが、この値を使ってはならない。グローバルIPは以下にアクセスすると自分のIPを把握することができる。
http://www.axisnetworks.biz/tools/gip/

gunicornをインストールしてサービス公開

http://torajirousan.hatenadiary.jp/entry/2019/04/22/181826

collectstaticを実行

サーバーに/usr/share/nginx/html/media,/usr/share/nginx/html/staticディレクトリがあることを確認してcollectstaticを実行する。

# ディレクトリがない場合以下を実行
$ mkdir /usr/share/nginx/html/media
$ mkdir /usr/share/nginx/html/static
python3.6 manage.py collectstatic

gunicornをインストール

 

$ pip install gunicorn

manage.pyがあるディレクトリに移動する。そして以下のコマンドを入力するとサービス公開できる。

$ gunicorn --bind 127.0.0.1:8000 config.wsgi:application

 

デーモンモードで公開する。

$ gunicorn --daemon --bind 127.0.0.1:8000 config.wsgi:application



settings.py以外のファイル名で製品settings.pyを作っている場合には、当該ファイルを使用する旨をオプションとして宣言する。

$ gunicorn --daemon --env DJANGO_SETTINGS_MODULE=config.product_settings --bind 127.0.0.1:8000 config.wsgi:application

postgresqlのパッケージについて

参考:https://lets.postgresql.jp/documents/tutorial/yum/yum

 

パッケージ名 主に格納しているもの
postgresql-libs libpqなどのPostgreSQLのライブラリ群。
PostgreSQL以外のパッケージが必要とすることもあります。
postgresql psqlpg_dumpなどのPostgreSQLのクライアントユーティリティ
postgresql-server initdbやpg_ctlなどのPostgreSQLのサーバユーティリティ。
DBMSサーバとして必要な機能はこれに含まれています。
postgresql-contrib pgbenchやpg_statstatementなどのPostgreSQLのcontribモジュール。
postgresql-devel PostgreSQLのヘッダやpg_configなどの開発用モジュール。
postgresql-doc PostgreSQLのドキュメント。
postgresql-test PostgreSQLリグレッションテスト用モジュール。

エラー: django.db.utils.ProgrammingError: syntax error at or near "WITH ORDINALITY" LINE 6: FROM unnest(c.conkey) WITH ORDINALITY co...

エラー

django.db.utils.ProgrammingError: syntax error at or near "WITH ORDINALITY"
LINE 6:                     FROM unnest(c.conkey) WITH ORDINALITY co...

以上のエラーが発生した。
これはdjangoのmigrateコマンドを実行したときのエラーである。

環境

環境
---------------centos7----------------
$ cat /etc/redhat-release

CentOS Linux release 7.6.1810 (Core)
--------------------------------------
---------------python-----------------
$ python3.6 -V

Python 3.6.6
--------------------------------------
---------------django-----------------
$ pip show django

Name: Django
Version: 2.1
Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design.
Home-page: https://www.djangoproject.com/
Author: Django Software Foundation
Author-email: foundation@djangoproject.com
License: BSD
Location: /home/*****/.local/lib/python3.6/site-packages
Requires: pytz
Required-by: django-allauth
-------------------------------------
--------------postgrsql--------------
$ postgres --version

postgres (PostgreSQL) 9.2.24
-------------------------------------

 

今までデプロイできていたのに何らかの理由でできなくなってしまった。

参考:https://stackoverflow.com/questions/55740085/django-db-utils-programmingerror-syntax-error-at-or-near-with-ordinality-line

上記によるとdjangoのバージョン2.1では、postgresqlは9.4以上を必要とするらしい。エラーの原因はこのバージョンが問題であった。

https://docs.djangoproject.com/ja/2.1/releases/2.1/#dropped-support-for-postgresql-9-3

エラー対処方法

postgeSQL公式のリポジトリを利用する。
https://yum.postgresql.org/

上記からpostgresqlリポジトリをインストールする。具体的には以下の流れで実行する。
postgresql公式url(上記)にアクセスする。
使いたいpostgresqlのバージョンを選択しクリック。例えばpostgreql11を利用するとする。
自分が使っているのosはcentos7なのでCentOS 7 - x86_64がリポジトリである。このリンクに対し、右クリックでリンクのアドレスをコピーを選択する。
次にサーバーのコマンドラインにリンクのアドレスを貼り付ける。

sudo yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

これでpostgeSQL公式のリポジトリを利用できる状態にできた。

sudo yum install postgresql11-server

これでバージョンを上げたpostgresqlを利用することでdjangoのmigrateコマンドをエラーなく実行することができた。

centos7 psycopg2のインストールエラー

sudo pip3.6 install psycopg2のエラー

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-70sqru_l/psycopg2/

以上のようなエラーが出た。この問題には以下のように解決する。

https://ja.stackoverflow.com/questions/46978/pip-%E3%81%A7%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%82%A8%E3%83%A9%E3%83%BC-command-python-setup-py-egg-info-failed

 

pip install --upgrade pip setuptools

上記コマンドを実行し、Successfully installed setuptools-41.0.0にアップグレード。再びpsycopg2のインストールを試みると次のエラーが出た。

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-kegfrwd6/psycopg2/

エラーが若干変わったと思いきや、同じ場所で引っかかっている気もする。

ググり方をエラー内容ではなく"centos psycopg2 error"で調べたら以下が出てきた。
https://stackoverflow.com/questions/12908807/cant-install-psycopg2-on-centos

これによると以下2コマンドを実行してみることと書いてあった。

yum install python-devel
yum install postgresql-devel

これらを実行してもpsycopg2はインストールできなかった。

./psycopg/psycopg.h:34:20: fatal error: Python.h: No such file or directory
     #include <Python.h>

このようなエラーが出てきたので次のように検索をかけて、解決案を探した。検索内容:./psycopg/psycopg.h:34:20: fatal error: Python.h: No such file or directory centos7

解決案:https://stackoverflow.com/questions/21530577/fatal-error-python-h-no-such-file-or-directory

For yum (CentOS, RHEL...):

sudo yum install python-devel   # for python2.x installs
sudo yum install python34-devel   # for python3.4 installs

そこで# yum install python36-develとした。その次にpsycopg2をインストールする事ができた。

少し振り返る

何が何だか分からなかったけれども、最初のエラーでは

Error: pg_config executable not found.
    
    pg_config is required to build psycopg2 from source.  Please add the directory
    containing pg_config to the $PATH or specify the full executable path with the
    option:

これが原因だった。これについてはこれが参考になると思われる。http://kumagonjp2.blog.fc2.com/blog-entry-204.html

次のエラーで./psycopg/psycopg.h:34:20: fatal error: Python.h: No such file or directory #include Python.hと出たのに対してはpython-develがないことが原因らしい。自分の場合はpython3.6だったので,yum install python36-develとしたらクリアできた。

centos7にdjangoをインストール

djangoのインストール

pipを予めインストールしておくこと。

sudo pip install django==2.2

その他djangoに必要と思われるもののリスト

# djangoで画像を表示させるアプリを作る時
pip install -y Pillow

# django-allauthを使う時
pip install django-allauth

# sendgridを使うとき
pip install django-sendgrid-v5
# stripeを使うとき

# DRFを使う時

# postgresqlを使う場合
pip install psycopg2-binary

参考:https://pypi.org/project/django-sendgrid-v5/

centos7にnginxをインストール

nginxをインストールする

まずnginxをインストールするためのレポジトリを準備する。以下のコマンドを実行しないとnginxのソースがないのでnginxのインストールできない。

yum install -y epel-release

nginxのインストール

sudo yum install -y nginx

nginxのサービス開始

sudo systemctl start nginx
sudo systemctl enable nginx

 

http(80番ポート)を開放

sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload

 

nginxの設定ファイルを編集

nginxの設定についてはnginx実践入門という本を読むと少しわかる。といっても以下の内容に帰結するので以下のコードを設定ファイルに張り付ければよい。

sudo vi /etc/nginx/conf.d/project.conf
server {
    listen  80;
    server_name 153.126.216.172;

    location /static {
        alias /usr/share/nginx/html/static;
    }

    location /media {
        alias /usr/share/nginx/html/media;
    }

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server_name に使用しているサーバのIPを記述すること。

設定ファイルの適正性を確認

sudo nginx -t
#以下のように表示されれば設定ファイルは問題ない。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
sudo systemctl restart nginx

初期化したサーバにssh接続できない件

エラー原因のコマンド

ssh root@***.***.***.***

エラーメッセージの一部

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:X5+91O42RA7+w6+TnMkNccoQIW30PeGYs9SeYwOAlkg.
Please contact your system administrator.

エラーになった背景

サーバーの環境構築に失敗したため、centos7をサーバーに再び入れ直しssh接続した。

エラー対処方法

クライアント側の.sshにknown_hostsがある。このファイルから当該サーバー分の記録をviを使って消去する。サーバーの記録はIPで記録されているのでそこを起点に探すと良い。
そして再びエラーが出てしまったsshコマンドを入力して接続する。

メモ

どうやら初めてサーバにssh接続するとクライアント側の.ssh/known_hostsに接続に関連した記録が残るようだ。初期化したサーバーには、その記録が残っているとエラーが出て接続できない結果になる。しかし意図がわからない。