chromeのHSTSキャッシュを削除する
http のリクエストが勝手にhttps にリダイレクトされる事案が発生しました。
状況としては↓な状況
サーバ側は設定を変更・再起動でよいけど ブラウザに残ったHSTS キャッシュが消えないかぎり、https にリダイレクトされ続けます。
キャッシュ消えるまで待つとかつらすぎるので、chromeのHSTSキャッシュを削除します
chromeのHSTSキャッシュを削除する方法
- chrome://net-internals/#hsts をchrome のURLに入力し、移動する。
Delete domain
の箇所に削除したいドメインを入力します。Delete
ボタンをクリックします。
終
vpn 接続時に SSH2_MSG_KEXINIT でハングするときの対処
- pritunl v1.18.902.26
- Tunnelblick 3.5.7 (vpn client)
pritunl をつかってVPN環境が構築した。
モバイル回線だと特に不便なくVPN接続できていたのだが、有線にしたところssh が繋がらない状態になった。
% ssh app-001.cameong.local : debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_6.2 debug1: Remote protocol version 2.0, remote software version OpenSSH_6.6.1 debug1: match: OpenSSH_6.6.1 pat OpenSSH* debug1: SSH2_MSG_KEXINIT sent
どうやらMTUの設定値関係してそう。
MTU = 1454
この PPPoE では Ethernet の MTU = 1500 の世界の中に、 RFC2516 的には 6 バイトの PPPoE へッダと 2 バイトの ppp へッダを加える。このため、 1500 - ( 6 + 2 ) = 1492 バイトまでのパケットしか通れないことになる。つまり MTU = 1492 にする。 しかし NTT 東日本の場合、更に内部のネットワークの事情で 「MTU = 1454 にしておけば、必ずどこでも通る」ということになっているらしい。 これらの数字は、 通常の Ethernet の通信に使われる 1500より小さくなるので、問題が起きる。と言える。
たしかに mtu 1500 になっている。
// ifconfig : utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500 inet 10.0.5.2 --> 10.0.5.2 netmask 0xffffff00
tunnelblick の設定にMTUの変更( link-mtu) を加える
verb 2 mute 3 push-peer-info ping 10 ping-restart 60 hand-window 70 server-poll-timeout 4 reneg-sec 2592000 sndbuf 100000 rcvbuf 100000 remote-cert-tls server + link-mtu 1454 comp-lzo no auth-user-pass key-direction 1
確認
% ifconfig : utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1384 inet 10.0.5.2 --> 10.0.5.2 netmask 0xffffff00
mtu 1454より小さくなってるけど。
この設定で、ssh 接続可能になりました。
気になる謎
- VPN接続なしの場合、en0 から接続してるのだが、en0 のmtu が1500 でも繋がるのなぜ。
- link-mtu 1545 なのに実際は1384 になってるのなぜ。
詳しい方、教えてください!
追記
- mtu 1454 だと時間がたったら、再度sshできなくなる。
- mtu 1400 でトライ
AWS RDS mysql 5.7.10だと360日でアカウント強制無効化されるとか聞いてないよ
- 日時: 2016/03/03
mysql 5.7 がAWS RDS で使えるということで、使ってみました。
そうすると、気になる記事を発見
アカウントの自動失効
MySQL 5.7で新しく追加された機能の1つに,アカウントの自動失効機能があります。これは最後にパスワードを変更した時間からデフォルトで360日が経過すると,そのアカウントをEXPIRE(無効化)しその後のログインを許可しないという強烈なオプションです。テストのために都度ビルドして利用するようなケースで問題になることは少ないかと思いますが,作成したイメージをそのまま長期間利用する(あるいは,ビルド時にユーザを作成し,その後アカウントが追加されることはあってもパスワードが変更されることはないようなケース)場合はこの機能をOFFにしておいた方がいいでしょう。
引用元
http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0010
MySQL 5.7.11でdefault_password_lifetimeのデフォルトは0に変更になりました!
引用元 http://yoku0825.blogspot.jp/2015/06/mysql-574defaultpasswordlifetime.html
とのことで
- mysql 5.7.0 ~ 5.7.10 は 360日経過するとデフォルトでアカウントが無効化される
- mysql 5.7.11 以降 デフォルトでアカウント無効化しない.
- AWS のRDS mysqlは 5.7.10
AWS が気を利かせてデフォルト値を変更しててくれてないかなと期待して見てみると
mysql> select @@default_password_lifetime; +-----------------------------+ | @@default_password_lifetime | +-----------------------------+ | 360 | +-----------------------------+ 1 row in set (0.01 sec)
はい、360日で無効化されてしまいますね。
AWSコンソールから default_password_lifetime を 0にするように変更します。
利用中のパラメーターグループを選択し、default_password_lifetime の値を0に変更します。
変更後
mysql> select @@default_password_lifetime; +-----------------------------+ | @@default_password_lifetime | +-----------------------------+ | 0 | +-----------------------------+ 1 row in set (0.00 sec)
無停止で変更できました。
これで強制無効化はなくなった。よかった。
django 1.8 のmodelformを使って、画像を登録・更新する
環境
- django 1.8
- python 2.7
目的
ユーザが自分自身の画像を登録できるようにする。
formで画像を登録するときの動きはほかのmodel でも利用可能です。
modelform を利用します。
変更に必要なファイルは次の通り。
- original_auth/models.py
- original_auth/urls.py
- original_auth/views.py
- original_auth/forms.py
- original_auth/templates/original_auth/original_user_update.html
一つずつ見ていきましょう。
original_auth/models.py
original_auth/models.py をみます。
主な初期値からの変更点は次の通り
- カスタムユーザを作成
- ログイン名をusernameからemail に変更
なお、2つとも画像登録に関係ない変更です。
どんなフィールドを使用しているか見てもらえればいいかなと。
// original_auth/models.py #-*- coding: utf-8 -*- from django.db import models from django.contrib.auth.models import AbstractUser,AbstractBaseUser,PermissionsMixin,UserManager from django.core.urlresolvers import reverse from django.dispatch import receiver from django.db.models.signals import post_save from django.conf import settings from django.utils.translation import ugettext_lazy as _ from django.utils import timezone from django.contrib.auth.models import ( BaseUserManager, AbstractBaseUser, _user_has_perm, _user_has_module_perms ) from django.core import validators from django.core.mail import send_mail class OriginalUser(AbstractBaseUser,PermissionsMixin): """User """ image = models.ImageField(_('image URL'),upload_to='user/images/%Y/%m/%d/', blank=True) username = models.CharField(_('username'), max_length=30, blank=True, help_text=_('Required. 30 characters or fewer. Letters, numbers and ' '@/./+/-/_ characters')) first_name = models.CharField(_('first name'), max_length=30, blank=True) last_name = models.CharField(_('last name'), max_length=30, blank=True) email = models.EmailField(verbose_name=_('email address'), max_length=255, unique=True) is_active = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) date_joined = models.DateTimeField(_('date joined'), default=timezone.now) objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username'] def __str__(self): return self.username def get_full_name(self): """ Returns the first_name plus the last_name, with a space in between. """ full_name = '%s %s' % (self.first_name, self.last_name) return full_name.strip() def get_short_name(self): "Returns the short name for the user." return self.first_name def email_user(self, subject, message, from_email=None, **kwargs): """ Sends an email to this User. """ send_mail(subject, message, from_email, [self.email], **kwargs) def get_absolute_url(self): return "/user/%i/" % self.id
original_auth/urls.py
つぎ original_auth/urls.py
from django.conf.urls import patterns, url from original_auth.views import user_update urlpatterns = patterns('', url(r'^(?P<pk>\d+)/update$', user_update, name='original_user_update' ), )
original_auth/views.py
つぎ、original_auth/views.py をみます。
- ログインユーザと違うユーザが変更画面にアクセスしたら表示させない
- 新規画像ファイルがなかったら、user情報を更新。
- 新規画像ファイルがあったら、あたらしくinstance を作成し、user情報を上書き。
もっといい方法があればしりたい。
// original_auth/views.py from django.http import HttpResponseRedirect from django.core.exceptions import PermissionDenied from django.contrib.auth.decorators import login_required from original_auth.models import OriginalUser from original_auth.forms import OriginalUserUpdateForm @login_required def user_update(request, pk): ''' :pk: unicode :request.user.pk: integer '''' request.user.pk == int(pk): u = OriginalUser.objects.get(id=pk) form = OriginalUserUpdateForm(request.POST or None, request.FILES or None,instance=u) args = {} if form.is_valid(): if request.FILES: instance = OriginalUser(image = request.FILES['image']) else: instance = u instance.id = u.id instance.email = u.email instance.password = u.password instance.username = form.cleaned_data['username'] instance.first_name = form.cleaned_data['first_name'] instance.last_name = form.cleaned_data['last_name'] instance.is_active = u.is_active instance.is_staff = u.is_staff instance.date_joined = u.date_joined instance.save() return HttpResponseRedirect("/user/%s" % (pk)) else: form = OriginalUserUpdateForm(request.POST or None, instance=u) args['form'] = form return render(request, 'original_auth/original_user_update.html', args) else: raise PermissionDenied
original_auth/forms.py
つぎ、 original_auth/forms.py をみます。
fields = '__all__'
にしてしまうと、(暗号化された)パスワードも見えるので、パスワード変更は別フォームで行ったほうが楽です。
変更したいフィールドだけ指定するようにします。
#-*- coding: utf-8 -*- from django import forms from original_auth.models import OriginalUser class OriginalUserUpdateForm(forms.ModelForm): image = forms.ImageField(required=False) class Meta: model = OriginalUser #fields = '__all__' fields = ['username','image','first_name','last_name']
original_auth/templates/original_auth/original_user_update.html
最後、templates です。
enctype="multipart/form-data"
を忘れずに。これがないと画像を扱えません。- 当然のことですが、
{% csrf_token %}
つけましょう
{% extends "base.html" %} {% block content %} <div> {% if form.has_errors %} {% for field in form.fields %} {% if field.error %} {{ field.error }} {% endif %} {% endfor %} {% endif %} <form method="POST" class="post-form" enctype="multipart/form-data">{% csrf_token %} {% csrf_token %} {{ form.as_p }} <input type="submit" value="{% trans 'Submit' %}" /> </form> </div> {% endblock %}
以上です。
.gitignore をお手軽に作成する
いちから.gitignoreを作成するのは大変なので github/gitignore を利用します.
- ライセンス: MIT
% mkdir repo_dir % cd repo_dir % wget https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore -O - >> .gitignore % wget https://raw.githubusercontent.com/github/gitignore/master/Global/Vim.gitignore -O - >> .gitignore % git init
django メールの送信テストを行う
django でメール送信するテストを行う。
settings.py の設定
// project/settings.py EMAIL_HOST = 'smtp.yourdomain.com' EMAIL_HOST_USER = 'your-username@yourdomain.com' EMAIL_HOST_PASSWORD = 'your-password' EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
django < 1.4 未満の場合
python manage.py shell >>> from django.core.mail import send_mail >>> send_mail('test email', 'hello world', to=['test@example.com'])
django 1.4 以上の場合
python manage.py shell >>> from django.core.mail import send_mail >>> send_mail('test email', 'hello world', 'your@email.com', ['test@email.com'])
http://stackoverflow.com/questions/6914687/django-sending-email