ikura1's log

備忘録

アジャイルとの出会いの話

はじめに

なんとなくお風呂に入っていて、アジャイルとの出会いの話を前大学のDiscordに書いたのを思い出して、ブログにも書いておこうかなっと思った次第です。これを書くきっかけになったのは、omoiyari.fmの第0回です。

lean-agile.fm

アジャイルとの出会い

アジャイルとの出会いは、大学のOBの方々が行っている講座のコミュニケーション講座の枠でチーム開発について教えていただいたのが、アジャイルとのきっかけになります。出会いとしては講座で、そのあとも様々なことで背中を押していただいた行動(転職)のきっかけになりました。出会い背中を押していただいて、最後に後押ししたのは、Podcastでした。転職でチームのことが自分ごとになっている状態で、Podcastで楽しく考えがんばっていることが話から伝わってきて、それが羨ましく、自分もそうなりたくなりました。
それが僕とアジャイルとの出会いと目覚めの話ですね。

---完---

Django環境の切り替えメモ

[Django]設定ファイルの切り替え

はじめに

Djangoの設定でセキュリティ設定をした場合、開発環境が楽しくない形になるので分けたい。
元々cookiecutter-djangoリポジトリを参考にしていたので、設定ファイルの切り替えを行いたかった。
だけど、Djangoでサイトを作ることを優先したので後回しにしていた。
セキュリティの設定で行う必要が出てきたので、やっていきます。

django-environ

django-environは環境変数の指定が気持ちよくなります。

インストール

pipenv install django-eviron

概要

django-environがないときー

import os

DEBUG = os.environ["DJANGO_DEBUG"]

DATABASES = {
    "default": {
        "ENGINE": os.environ["POSTGRES_ENGINE"],
        "NAME": os.environ["POSTGRES_NAME"],
        "USER": os.environ["POSTGRES_USER"],
        "PASSWORD": os.environ["POSTGRES_PASSWORD"],
        "HOST": os.environ["POSTGRES_HOST"],
        "PORT": os.environ["POSTGRES_PORT"],
    }
}

あるときー!

import environ

DEBUG = env.bool("DJANGO_DEBUG", default=False)

DATABASES = {"default": env.db("DATABASE_URL")}

はい、スマートになりましたね。
最高です。

詰った点

困ったのは、GAEを使っているんですが、CloudSQLの参照設定に詰りました。
ローカルの設定は下記になるんですが、ColudSQLの場合はunix_socketにインスタンス名を指定することを知らずに設定が反映されねえ!!
って悩んでいました。

CloudSQLはhostではなく、unix_socketにインスタンスを設定するんですね。

  • ローカルでの設定
f"mysql://{USER}:{PASSWORD}@{HOST}:{PORT}/{DBNAME}"
"mysql://hoge:hogehoge@127.0.0.1:3306/hoge_db"
  • CloudSQLでの設定
f"mysql://{USER}:{PASSWORD}@/{DB_NAME}?unix_socket=/cloudsql/{INSTANCE_CONNECTION_NAME}"
"mysql://hoge:hogehoge@/hoge_db?unix_socket=/cloudsql/todo:asia-northeast2:todo-db"

環境の分離

フォルダ構成

フォルダ構成をcookiecutterを参考に下記にした。

$ tree ./config/ -I '__pycache__'
./config/
├── __init__.py
├── settings
│   ├── __init__.py
│   ├── base.py
│   ├── local.py
│   └── production.py
├── urls.py
└── wsgi.py

1 directory, 7 files

cookiecutterはローカルと本番以外に、test環境用の設定が存在する。
テストコードがまだ書けていないので、今回は保留して後日追加します。

開発と本番での設定分離

開発環境で設定すると閲覧できなくなるセキュリティ回りやDBの参照回りを本番のみの設定として、他はbaseで共有するという形です。
設定でわからない部分がありますが、cookiecutter-djangoでは設定項目の上にドキュメントのurlが書いてあるので非常に助かる。
作成は参考にしつつ、コピペしつつ、書きつつといった感じです。

↓は添付用にざっくり削ってます。
開発

# local.py
from .base import *
from .base import env

# GENERAL
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#debug
DEBUG = True
# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
# localと本番で同じDBを使っているため今はenvを参照している
# TODO: 設定回りの調整が終わり次第, DBを分離させる
SECRET_KEY = env(
    "DJANGO_SECRET_KEY",
    default="ObpY86bMfPs0X5HfluLGFslLDFnHdLQ2sjR8QX17xivRR0XRPFK7fMU0uqWE10nK",
)

ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"]

本番

# production.py
from .base import *
from .base import env

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env("DJANGO_SECRET_KEY")

ALLOWED_HOSTS = ["timetask.appspot.com"]

# ADMIN
# ------------------------------------------------------------------------------
ADMIN_URL = env("DJANGO_ADMIN_URL")

# SECURITY
# ------------------------------------------------------------------------------
# HSTS
# SECURE_HSTS_SECONDS = 518400
# https://docs.djangoproject.com/en/dev/topics/security/#ssl-https
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-seconds
# TODO: set this to 60 seconds first and then to 518400 once you prove the former works
SECURE_HSTS_SECONDS = 60
SECURE_HSTS_INCLUDE = True
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload
SECURE_HSTS_PRELOAD = True

参照の切り替え

参照元をsettings.pyのところをsettings.localとsettings.productionに切り替えました。

  • Before
# wsgi.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
# manage.py
def main():
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
  • After
# wsgi.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
# manage.py
def main():
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")

次にやること

  • セキュリティ項目でわからんことのドキュメント読む
  • テスト書く
  • ファイルアップロード回りの実装
    • アカウントアイコンにする

参考サイト

https://github.com/audreyr/cookiecutter

https://github.com/pydanny/cookiecutter-django

https://qiita.com/moonwalkerpoday/items/9da47dda80d3ddac9a62

Djangoサイトのセキュリティ見直しメモ

[Django]セキュリティの見直し

はじめに

はじめてDjangoを使ったので、セキュリティ回りがどうなっているのかが気になったので調べつつ設定をしていった。

./manage.py check --deploy

System check identified some issues:

WARNINGS:
?: (security.W004) You have not set a value for the SECURE_HSTS_SECONDS setting. If your entire site is served only over SSL, you may want to consider setting a value and enabling HTTP Strict Transport Security. Be sure to read the documentation first; enabling HSTS carelessly can cause serious, irreversible problems.
?: (security.W006) Your SECURE_CONTENT_TYPE_NOSNIFF setting is not set to True, so your pages will not be served with an 'x-content-type-options: nosniff' header. You should consider enabling this header to prevent the browser from identifying content types incorrectly.
?: (security.W007) Your SECURE_BROWSER_XSS_FILTER setting is not set to True, so your pages will not be served with an 'x-xss-protection: 1; mode=block' header. You should consider enabling this header to activate the browser's XSS filtering and help prevent XSS attacks.
?: (security.W008) Your SECURE_SSL_REDIRECT setting is not set to True. Unless your site should be available over both SSL and non-SSL connections, you may want to either set this setting True or configure a load balancer or reverse-proxy server to redirect all connections to HTTPS.
?: (security.W012) SESSION_COOKIE_SECURE is not set to True. Using a secure-only session cookie makes it more difficult for network traffic sniffers to hijack user sessions.
?: (security.W016) You have 'django.middleware.csrf.CsrfViewMiddleware' in your MIDDLEWARE, but you have not set CSRF_COOKIE_SECURE to True. Using a secure-only CSRF cookie makes it more difficult for network traffic sniffers to steal the CSRF token.
?: (security.W018) You should not have DEBUG set to True in deployment.
?: (security.W019) You have 'django.middleware.clickjacking.XFrameOptionsMiddleware' in your MIDDLEWARE, but X_FRAME_OPTIONS is not set to 'DENY'. The default is 'SAMEORIGIN', but unless there is a good reason for your site to serve other parts of itself in a frame, you should change it to 'DENY'.

System check identified 8 issues (0 silenced).

issues

https://docs.djangoproject.com/ja/2.2/topics/security/

security.W004 httpに接続された場合、httpにリダイレクトするヘッドを挿入してはどうかという警告。 不用意にオンにすると取り返しの使ないことになるらしい。

SECURE_HSTS_SECONDS = 60
# SECURE_HSTS_SECONDS = 36000
# SECURE_HSTS_INCLUDE = True

下記を参考設定するのが良い。 https://docs.djangoproject.com/ja/2.1/ref/middleware/#http-strict-transport-security

  • 今はGAEがsslにしてくれているようだからオンにしても大丈夫なのかな?

security.W005 HSTSにサブドメインが含まれていないので、サブドメイン接続からの攻撃が想定され危ないよ!っという警告

SECURE_HSTS_INCLUDE_SUBDOMAINS = True

security.W006 コンテンツを自動判定して、指定している”Content-Type”と違う場合でも実行されてしまうため、”Content-Type-Options: nosniff”を指定しようぜっという警告。

SECURE_CONTENT_TYPE_NOSNIFF = True

security.W007 ブラウザにあるXSSフィルタx-xss-protection: "``1; mode=block``"``;を有効にして、XSS攻撃の防止に役立てようぜっという警告

SECURE_BROWSER_XSS_FILTER = True

security.W008 HTTPとHTTPSを両方使う場合、でない限りリダイレクトするようにするといいよっという警告

SECURE_SSL_REDIRECT = True

security.W012 HTTPSのみにCookieを転送可能なようにすることで、セッションハイジャックを困難にすると良いぞという警告

SESSION_COOKIE_SECURE = True

security.W016 HTTPSのみにCSRS Cookieを転送可能なようにすることで、セッションハイジャックを困難にすると良いぞという警告

CSRF_COOKIE_SECURE = True

security.W018 デプロイでDEBUGモードは危ないぞ!!っという警告

DEBUG = False

security.W019 デフォルトはsameoriginになっており、同じサイト内のページでフレームに読み込まれた場合にのみ表示される。 denyでは全てに置いてページをフレーム内に表示することはできない。

X-OPTION = "DENY"

security.W021 設定してないとブラウザのプリロードリストに登録されないぞ!っという警告 プリロードリストにホストが登録されている場合、最初に接続する段階からHTTPSでの接続します。

SECURE_HSTS_PRELOAD = True

次にやること

参考サイト

Django におけるセキュリティ | Django ドキュメント | Django

現場で使える Django のセキュリティ対策 / Django security measures for business (DjangoCon JP 2019) - Speaker Deck