DreamerDreamのブログ

夢想家の夢です。〜揚げたてのモヤっとしたものをラフレシアと共に〜

Apacheで簡単なDDOS対策「mod_evasive」

Apacheではサーバーへの大量パケットが投げられるというDDOS攻撃の対策として

mod_evasive

というモジュールを利用することが出来ます。

 

これは大量アクセスへ対策するもので、デフォルトのままで

 

  • 同一ページへ1秒間に2回以上のアクセスでブロックリスト追加
  • 同一サイトへ1秒間に50回以上のアクセスでブロックリスト追加
  • 最後のアクセスから10秒後にブロックリスト解除

 

という挙動をしてくれるものです。

 

手順として

httpd -l

を実行。出て来る一覧に

mod_so.c

が存在することを確認します。

無ければhttpd24u-develというものをインストールする必用があるようです。

 

httpd -M | grep evasive

コマンドで

evasive~~

が存在しないことを確認します。存在していれば既に導入済みです。

 

インストールします

sudo yum install epel-release

sudo yum install --enablerepo=epel mod_evasive

 

 

設定します。

sudo nano /etc/httpd/conf.d/mod_evasive.conf

デフォルトではこのようになっていました。

DOSHashTableSize 3097 プロセスのハッシュテーブルサイズ

DOSPageCount 2  同一ページへのアクセス数

DOSSiteCount 50 同一サイトへのアクセス数

DOSPageInterval 1 何秒間に上記アクセス数をカウントするか

DOSBlockingPeriod 10 何秒後に解除するか

 

 

Apacheの再起動

sudo systemctl restart httpd.service

 

インストールの確認

httpd -M | grep evasive
evasive20_module (shared)

 

ひとまずこれでOKです。

f:id:DreamerDream:20181102091314p:plain

 

【手順】DOS対策(mod_evasive) - Qiita

Djangoの使い方⑨Apacheで複数のDjangoプロジェクトを綺麗に振り分ける方法

前回記事 

dreamerdream.hateblo.jp

 

 

Apacheで静的なページを振り分ける方法はコチラ↓今回はこの応用です。

dreamerdream.hateblo.jp

 

Apacheは2.4です)

静的ページと同じようにDjangoで作ったページも振り分けることが出来ますが、WSGIモジュールを挟むので少しだけ面倒です。

まずはDjangoで作ったページをApacheで表示できるようにしましょう。

※注意

以前に「Djangoの使い方④」の方法とほぼ同じですが、今回はVSPを契約したのでRaspbianではなくCentOS向けの記事になります。Raspbianの場合も同じように出来ると思いますが未確認です。

wsgiモジュールをインストールしていれば

/etc/httpd/conf.modules.d/10-wsgi-python3.6.conf

という.confファイルが出来ていると思います(バージョンによって違うかもですがwsgiとあればおそらくそれでしょう)

中身は

<IfModule !wsgi_module>
  LoadModule wsgi_module modules/mod_wsgi_python3.6.so

</IfModule>

とだけなので.soファイル(モジュール)を読んでいるだけです。

 

ここに、

<IfModule !wsgi_module>
LoadModule wsgi_module modules/mod_wsgi_python3.6.so

  WSGIScriptAlias / /home/django/draemon/draemon/wsgi.py
  WSGIPythonPath /home/django/draemon/

  <VirtualHost *:80>
    ServerName draemon.domain.com

    <Directory /home/django/draemon/draemon>
      <Files wsgi.py>
        Require all granted
      </Files>
    </Directory>
  </VirtualHost>

</IfModule>

このように記述することでDjangoページを表示できます。

 

 

2つのページを振り分けるにはまず2つのDjangoプロジェクトを作り、それぞれ単体で表示できるようにしておきましょう。

例としてdraemonnobitaの2つのプロジェクトを取り扱います。

 

できたらそれぞれのプロジェクトのディレクトリを

WSGIPythonPath /home/django/draemon:/home/django/nobita

という風にWSGIPythonPathに2つのページを:を付けて(Windowsの場合は;だそうです)記述し、その後<VirtualHost>の設定をすることで複数のページが表示出来ます。

 」

 

という情報をWebページで見てそのように設定したのですが、この情報で設定した場合pythonのパスがダブってしまってうまくいきませんでした。

どううまくいかなかったかといいますと、draemonとnobitaに含まれる両方のwsgiファイルが読まれ、両プロジェクトのsettingファイルが読まれたことで

  • debug=Trueにしているはずのプロジェクトエラー内容が表示されない、またその逆が起こる。
  • プロジェクトに存在しているはずのページが開けない。
  • プロジェクト内に存在していないはずのアプリのURLで別のプロジェクトアプリが動く

という事象が起こり、最初どういうことだか理解が出来なかったのですが、

プロジェクトのデバッグエラー内容が表示された際に

PythonPath=[

/home/django/draemon

/home/django/nobita

/usr////////

 (内容はこんな感じだっと思う)

という風に2つのプロジェクトファイル名が出て来て、1つのブロジェクトのはずなのに複数のプロジェクトパスが読まれているという事に気が付きました。

 

こうなると、場合によってはdraemonのページが表示され、場合によってはnobitaのページが表示されるという何ともトンチンカンなページになってしまいます。

 

で、結論ですがDjangoの「デーモンモード」を使う事で解決します。

Djangoでは(に限らず?)WSGIを動かす時に「組み込みモード」と「デーモンモード」という2つのモードがあり、WSGIPythonPathを設定する上記の方法は組み込みモードという設定だそうです。

 

デーモンモードで動かすには<VirtualHost>内に

WSGIDaemonProcessとWSGIScriptAliasに適切なパスとプロセス名を記述する必用があるようです。

 

僕もあれこれ試した結果なのでうまく説明できませんが、結果的に下のように設定することでうまくプロセスを分担して動かす事ができました。

<IfModule !wsgi_module>
LoadModule wsgi_module modules/mod_wsgi_python3.6.so

 

  <VirtualHost *:80>

    ServerName draemon.domain.com
    WSGIDaemonProcess draemon user=apache group=apache maximum-requests=10000 python-path=/home/django/draemon

    WSGIScriptAlias / /home/django/draemon/draemon/wsgi.py process-group=draemon
    CustomLog   logs/draemon.access.log combined    ErrorLog   logs/draemon.error.log
    <Directory /home/django/draemon/draemon> 

       <Files wsgi.py>

         Require all granted

       </Files>
  </VirtualHost>

  <VirtualHost *:80>

    ServerName nobita.domain.com
    WSGIDaemonProcess nobita user=apache group=apache maximum-requests=10000 python-path=/home/django/nobita

    WSGIScriptAlias / /home/django/nobita/nobita/wsgi.py process-group=nobita
    CustomLog   logs/nobita.access.log combined    ErrorLog   logs/nobita.error.log
    <Directory /home/django/nobita/nobita> 

       <Files wsgi.py>

         Require all granted

       </Files>

    </Directory>

 

 

</IfModule>

 

しかし、この方法ではコードが非常に見辛くなり、このままではメンテナンスもし辛いですね。 

 

そこで、上リンク先「静的ページの振り分け」と同様にInclude文を使って見やすくしましょう。

/etc/httpd/conf.modules.d/extra

ディレクトリを作り

/etc/httpd/conf.modules.d/10-wsgi-python3.6.conf

の内容を下記のようにします。

<IfModule !wsgi_module>
  LoadModule wsgi_module modules/mod_wsgi_python3.6.so
  Include conf.modules.d/extra/main.conf

</IfModule>

 

こうすると/etc/httpd/conf.modules.d/extra/main.confファイルがインポートされます。

そして、

/etc/httpd/conf.modules.d/extra/main.conf

を作ります。

main.confでさらにImport文を使って振り分けることでページの管理をします。


Include conf.modules.d/extra/vhost-draemon.conf
Include conf.modules.d/extra/vhost-nobita.conf

と、いう風にIncludeで別々の設定ファイルを読ませます。

/etc/httpd/conf.modules.d/extra/vhost-draemon.conf

 に

  <VirtualHost *:80>

    ServerName draemon.domain.com
    WSGIDaemonProcess draemon user=apache group=apache maximum-requests=10000 python-path=/home/django/draemon

    WSGIScriptAlias / /home/django/draemon/draemon/wsgi.py process-group=draemon
    CustomLog   logs/draemon.access.log combined    ErrorLog   logs/draemon.error.log
    <Directory /home/django/draemon/draemon> 

       <Files wsgi.py>

         Require all granted

       </Files>
  </VirtualHost>

 

 

/etc/httpd/conf.modules.d/extra/vhost-nobita.conf

 に

<VirtualHost *:80>

    ServerName nobita.domain.com
    WSGIDaemonProcess nobita user=apache group=apache maximum-requests=10000 python-path=/home/django/nobita

    WSGIScriptAlias / /home/django/nobita/nobita/wsgi.py process-group=nobita
    CustomLog   logs/nobita.access.log combined    ErrorLog   logs/nobita.error.log
    <Directory /home/django/nobita/nobita> 

       <Files wsgi.py>

         Require all granted

       </Files>

    </Directory>

とを記述します。

 

結果的に.confの内容自体は一番上と全く同じですが、設定ファイルを分けることでページ追加や除外等の管理操作が簡単になり、イージーミスで他のページの設定を弄ってしまうなんてことも防げます。

はい。これで複数のDjangoページが好きなだけ作れますね。

f:id:DreamerDream:20181015110858p:plain

 

 

 <参考ページ>

複数のDjangoのアプリケーションをApacheに連携させたい。 - Tihiroの頭を休めるIT教室

Como usar Django con Apache y mod_wsgi | Django documentation | Django

 

 

 次回、サイトのhttps化です。

dreamerdream.hateblo.jp

 

Apacheで同じIPアドレスでドメインごとにWebページを綺麗に振り分ける方法

Webサーバーの作り方を知ってホームページを自作するとき、「複数のページをドメインごとに振り分けたい」と思うことがあるでしょう。 

 

ドメインIPアドレスと接続ポートの関係性を知った段階の人なら

「複数のドメインで複数のホームページを開くにはポートを複数増やさないといけないんじゃないのか?」

という疑問を持つと思います。持ちませんか?僕はすこし前まではそう思ってました。

 

つまり、

hello.com

world.com

という2つのドメインを取得してホームページを運用する場合、

hello.comはそのままアクセス出来るけど

world.comに繋ぐとwwwアクセスでは同じ80番ポートなので同じページが表示されてしまう!

だからworld.com:81という風に接続ポートを分ける必用があるんじゃないの?

f:id:DreamerDream:20181013093903p:plain

という疑問です。

 

答えは、違います!同じIPアドレス、同じ80番ポートでもアクセスしてきたアドレスによってApache等のサーバーソフトでドメインごとにページをいくつでも振り分けることが出来るのです!

f:id:DreamerDream:20181013094032p:plain

Apacheの場合VirtualHostという機能を利用します。

 

例えば、静的なページで設定する場合

CentOS、Apache2.4使用の場合)

-- /etc/httpd/conf/httpd.conf --

Listen 80

<VirtualHost *:80>

    Alias / /var/www/hello/
    ServerName hello.domain.jp

    CustomLog   logs/hello.access.log combined

    ErrorLog   logs/hello.error.log

    <Directory /var/www/hello>

        Require all granted

    </Directory>

</VirtualHost>

<VirtualHost *:80>

    Alias / /var/www/world/
    ServerName world.domain.jp

    CustomLog   logs/world.access.log combined

    ErrorLog   logs/world.error.log

    <Directory /var/www/world>

        Require all granted

    </Directory>

</VirtualHost>

 

こう記述することで

hello.domain.jpにアクセスされたページは/var/www/helloディレクトリへ、

world.domain.jpにアクセスされたページは/var/www/worldディレクトリへ

と振り分けることができます。

CustomLog   logs/hello.access.log combined

ErrorLog   logs/hello.error.log

この記述は、アクセスログとエラーログを見やすく振り分けています。

こすると/var/log/httpd/内にhello.access.logworld.access.logといったログがページによって振り分けられるので便利です。

 

また、デフォルトでモジュールをインポートしている項目に

Include conf.modules.d/*.conf

という記述が見られると思いますが、同じように.confファイルとすることで設定ファイルをファイルとして振り分けることも出来ます。

例えば、

/etc/httpd/conf/extra/hello.conf

 

<VirtualHost *:80>

    Alias / /var/www/hello/
    ServerName hello.domain.jp

    CustomLog   logs/hello.access.log combined

    ErrorLog   logs/hello.error.log

    <Directory /var/www/hello>

        Require all granted

    </Directory>

</VirtualHost>

 

 

/etc/httpd/conf/extra/world.conf

 

<VirtualHost *:80>

    Alias / /var/www/world/
    ServerName world.domain.jp

    CustomLog   logs/world.access.log combined

    ErrorLog   logs/world.error.log

    <Directory /var/www/world>

        Require all granted

    </Directory>

</VirtualHost>

 

と記述したページを別々に作った場合、

/etc/httpd/conf/httpd.conf

Listen 80

Include conf/extra/hello.conf 

Include conf/extra/world.conf

 

と記述することで上と同じように連続した設定として読み込むことが出来ます。

またワイルドカード

Include conf/extra/*.conf

とすることでextraディレクトリ内の設定を全部読むということも出来ます。 

ムームードメインで取得したドメインをConohaに設定!ドメインって盗まれないの?

今回はDNSの設定ですが、疑問点が出て来ましたのでもし誰か解る方あったら教えていただきたいです。

 

まずはムームードメインドメインを取得します。

これは簡単!

好きなドメイン名で検索して、空きがあればそのまま取得できます。

f:id:DreamerDream:20181012130535p:plain

僕はテスト用アドレスが欲しかっただけなので、とりあえず1年だけの契約で99円で.tokyoドメインを取得しました!気に入ったら自動更新にします。

 

Conohaのネームサーバーで設定する

この方法は「Conoha ムームドメイン」で調べるとすぐ出て来ます。 

取得したら、Conohaの管理画面のネットワーク情報にある「IPアドレス」をコピーしておきましょう。

f:id:DreamerDream:20181012122005p:plain

 

次に「DNS」を選択して、「+ドメイン」ボタンで取得したドメインを登録します。

f:id:DreamerDream:20181012121910p:plain

 

ドメイン名にドメインを登録したら「保存」しましょう。

GeoDNSは有料サービスなので無効にしておきます。

f:id:DreamerDream:20181012121922p:plain

 

保存しましたら、一覧から先ほど登録したドメインを選択します。

f:id:DreamerDream:20181012121934p:plain

 

鉛筆マークを押して編集モードに入り、「+」ボタンでドメイン情報を追記します。

タイプはA(通常) 名称はwww 値の所に先ほどこぴーしたIPアドレスを入力します。TTLは空欄でOK

 

f:id:DreamerDream:20181012122013p:plain

保存してConoha側の設定は完了です。

上の「値」にある「ns-a1.conoha.io」「ns-a2.conoha.io」「ns-a3.conoha.io」をコピーしておきます。

 

/////////////// 

次にムームドメインの管理サイトを開きます。 

ネームサーバー設定変更を選択します。

f:id:DreamerDream:20181012121947p:plain

GMOパパボ以外のネームサーバーにチェックを入れます。

f:id:DreamerDream:20181012122020p:plain

ネームサーバー1〜3まで、先ほどの値の項目を入力します。

f:id:DreamerDream:20181012122028p:plain

これで完了です。

f:id:DreamerDream:20181012122037p:plain

直後にアクセスしようとしても反映されていません。

反映まで数日待ちましょう。

 

 

 

ん?ここでふとおかしなことに気が付きました。

ドメイン名って「挙手性」なの??

 

 

疑問点

 

つまりこういうことです。

今しがた設定したのはConohaの方でIPアドレスドメインを関連付けて広めるよう設定しました。

ドメインを管理しているムームーにはConohaが設定しているネームサーバーなら許可するよう設定しました。 

f:id:DreamerDream:20181013082743p:plain

そしたら、こういう動きになるんですよね?

これなら正常動作!!

f:id:DreamerDream:20181013083017p:plain

 

しかし、ですよ?

仮にConohaのネームサーバーを使っている人が設定ミスや故意に自分のネームサーバーで他人の取得したドメインネームを名乗らせたらどうなるのという疑問が生まれます。

特にパスワードやPINコードといった設定項目はありませんでした。

確認しているのはネームサーバー名だけです。

f:id:DreamerDream:20181013083642p:plain

このようにダブってネームサーバーは伝えるのでしょうか?

f:id:DreamerDream:20181013083805p:plain

どうなるのでしょうか?

先に名乗った方が勝ち?だったらサーバー移動とかの場合はどうなるの?

メンテナンス中に乗っ取られたりしないの??

僕の認識が間違っているのでしょうか?

サッパリわからないので、エライ人!誰か教えてください!!

 

 

ムームードメインからのIP設定方法

 

ということで、よく解らないシステムを使う事は避けて、ムームードメインのネームサーバーでIPアドレス指定する方法がありましたので、そちらで設定することにします。(固定IPでないと設定は無理です。)

ネームサーバー設定変更の項目でムームDNSのネームサーバーを使用するようチェックを入れます。

f:id:DreamerDream:20181012164458p:plain

そして、ムームDNSの項目から

ムームDNSのセットアップ情報変更から該当するドメインの「変更」ボタンを押します

f:id:DreamerDream:20181012164508p:plain

そうすると「設定2」でサブドメイン、種別、内容、優先度が問われます。

サブドメインはsample.comであれば[hello]と設定するとhello.sample.comというふうにサブドメインが設定できます。使わないのであれば空欄でOK!

種別は通常「A」だそうです(その辺は解っていません)

内容はサーバーのIPアドレスを入れます「123.45.67.89」のように

優先度はデフォルト50で数値が低くなるほど優先度が高くなるそうです。空欄でOKです。

f:id:DreamerDream:20181013090355p:plain

 

 以上が、ムームーでのIPアドレスを指定した設定方法です。

Djangoの使い方⑧テキストファイルの改行\r\nコードをHTMLの<br>に変換する

前回記事

dreamerdream.hateblo.jp

 

 

Djangoでテンプレートにテキストを表示する場合、通常の方法でテキストを貼付けるとソースコードでは改行されているけどHTMLの<br>タグが無いので改行ができていない文がずらーっと表示されます。

f:id:DreamerDream:20181004102234p:plain

例えば、文字列

'abcdefg.......xys\r\nTEST!'

という改行コードが含まれた文字をそのままテンプレートの

{{ set_text  }}

に貼付け、ブラウザで見ると

f:id:DreamerDream:20181004095659p:plain

 

こうなります。

こうしない為には'\r\n'コードをpythonで置き換えてやれば良いや!と単純に考え

texts = 'abcdefg.......xys\r\nTEST!'
texts = texts.replace('\n','<br />')

と単純に置き換え、ブラウザで見ると

f:id:DreamerDream:20181004095958p:plain

 

はい、こうなります。

どうなってんの?とソースを見ると、ご丁寧にエスケープ処理されてしまいます。

f:id:DreamerDream:20181004100031p:plain

困った!

 

 

じゃあどうすんの?って話ですけど、PythonでどうにかしようとせずDjangoの機能を使えばめちゃくちゃ簡単に解決します!

なんと、テンプレートの項目に”| linebreaksbr”と書いてあげるだけ!

{{ set_text | linebreaksbr }}

これで勝手に改行コードが置き換えられます。ブラウザで見ると

f:id:DreamerDream:20181004100503p:plain

ソースを見ると、今度はソースでは改行されていませんが代わりに<br>タグが含まれています。

f:id:DreamerDream:20181004100540p:plain

 

 

<p>タグで囲いたい場合は

{{ set_text | linebreaksbr | linebreaks }}

とすると、ブラウザのソースを見るとちゃんと<p>タグが入っています。

f:id:DreamerDream:20181004101050p:plain

 

メチャメチャ簡単やんっ!という機能ですがなかなか調べるのに難儀しました。

こういう機能は「フィルタ」と呼ばれるそうで、こちら↓のブログが非常に詳しいです。

Django、よく使うフィルタ - naritoブログ

フィルタは自作も出来るそうですし、逆にHTMLを直接書きたいという場合にはOFFに出来るそうです。

Djangoの便利機能、使いこなせたら本当に自由自在んだろうな。と感じました。

 

 

dreamerdream.hateblo.jp

 

 

Djangoの使い方⑦formの使い方とテンプレートで動的なページを作る方法

 前回記事

dreamerdream.hateblo.jp

 

 

formは動的なWebページでは書かせない要素です。

基本的にはGETかPOSTでサーバーにリクエストを飛ばします。

(PUTやDELETEリクエストもあるけど必要性を感じません。)

 

index.html

<form method="post" action="">
Hello!<br>
<p>
<textarea name="text" rows="5" cols="30">テキスト内容</textarea>
</p>

<input type="submit" value="送信"><input type="reset" value="リセット">
</form>

 

というフォームを書いた場合

f:id:DreamerDream:20181012132959p:plain

と表示されます。表示されるだけで何も起こりません。

何を書いても送信かリセットを押すと最初の文章が戻ります。

 

1つづつ見ていきます。

<form method="post" action="">

ここからPOSTリクエストされますよーという指定です。

リクエストを送信した後、action=で指定されたページに飛びます。何も指定が無ければページはそのままで更新されます。


Hello!<br>

単なる文字列です。説明の必用は無いでしょう。


<p>
<textarea name="text" rows="5" cols="30">テキスト内容</textarea>
</p>

テキスト入力が可能なテキストエリアです。

name=はリクエストを送信した時に「’text’の内容ですよー」という印です。

rowsは行、colsは幅です。

 

<input type="submit" value="送信"><input type="reset" value="リセット">

送信ボタンとリセットボタンです。

type='submit'とするとボタンを押すとform内容をPOST形式で飛ばします。

type='reset'とするとボタンを押すとformの内容が全てリセットされます。

</form>

 

とまあ、超単純なテキストの内容をリクエストするだけのフォームです。

ちなみに、GETリクエストは文字コードや文字数制限やらややこしいですが、POSTは文字コードや文字数は無制限で送信できますのでこのようなテキストエリアならPOSTが望ましいです。

 

で、このリクエストをDjangoではどのように受け取るのかといいますと、辞書形式でnameを指定するだけなのですごく簡単!

views.py

from . import forms

from django.shortcuts import render

def form(request):

  text = request.POST['test']

必用なのは、これだけ。

request.POSTで先ほどのフォームの中でname指定した値を辞書形式で取得出来ます。

これでtextにテキストエリアの内容が格納されます。

あとは煮るなり焼くなりプログラム次第でお好きにどうぞ!ってことです。

request.GETを指定するとGET形式で取得出来ます。

 

GETかPOSTかの判定は

if request.method == 'POST':

で判定できますので

同じアドレスでもGETとPOSTを混在させることが容易になります!面白い!

 

views.py(必用な部分だけ抜き出しているのでこのままじゃ動かないかも)

def form(request):
  if request.method == 'GET':
    d={
      'message': 'GET!',
      'text': 'テキスト内容',
    }
    return render(request, 'index.html',d)

  elif request.method == 'POST':

    text = request.POST['text']  

    result = 'text内容は'+text+'でした。'

    d={

      'message': 'POST!',

      'text':result,

    }

    return render(request, 'index.html',d)

 

こうすると、GETでのアクセスとPOSTでのアクセスの挙動を変えることができます。

結果の挙動を変えるため、最終的にrenderでテンプレートに貼付けています。

 

テンプレートの書き方はこんな感じです。

index.html

<form method="post" action="">
{% csrf_token %}
{{ message  }}<br>
<p>
<textarea name="text" rows="5" cols="30">{{ text }}</textarea>
</p>

<input type="submit" value="送信"><input type="reset" value="リセット">
</form>

※{% csrf_token %}の部分はDjangoが生成する不正アクセス予防の為の値になります。POSTリクエストを飛ばす際にはこれを書かないとエラーが出ます。

 

テンプレートは {{  }}で囲われた部分が、views.pyのd{}で指定していた値に置き換えられる便利な機能です。(ちなみに、軽量フレームワークのBottleでも同じような機能がありますが使いにくいです。)

これを利用すると、リストをそのままテンプレートに飛ばす事が出来ます!

フォームのselectを利用する場合、通常では

index.html

<select name="number">
 <option value='0'>0</option>

 <option value='1'>1</option>

 <option value='2'>2</option>

 <option value='3'>3</option>

 <option value='4'>4</option>
</select>

 

と書くと、このような選択ボタンが表示されます。

f:id:DreamerDream:20181012142056p:plain

Djangoのテンプレート利用では

index.html

<select name="number">
{% for num in nums %}
<option value='{{ num }}'>{{ num }}</option>
{% endfor %}
</select>

と書き、先ほどのtextへの代入と同様に

views.py

nums = ['0','1','2','3','4','100','200','300']

  d={

      'number': nums,

    }

    return render(request, 'index.html',d)

 

とnameを指定してリストを代入すれば、テンプレートのfor分で繰り返し処理して綺麗に並べてくれます。

ファイルの操作など、内容が変動するものを代入するにはうってつけの機能ですね。

f:id:DreamerDream:20181012155235p:plain

 

 

dreamerdream.hateblo.jp

 

<参考> 

https://eiry.bitbucket.io/tutorials/tutorial/forms.html

3Dプリンターのプリントヘッドを交換してみた

以前に弾性フィラメントの上手な使い方として記事を書いていました。 

dreamerdream.hateblo.jp

しかし、とうとうこの方法でも長時間の出力が怪しくなって来ましたのでメンテナンスすることにしました。

 

原因はおそらくプリントヘッドのバレル内にあるPTFEチューブ(テフロンチューブ)の寿命と考えられます。

以前、たまたまPTFEチューブが外れたときに結構焦げがついていました。

このところPLAでも安定しない時があったのでそろそろかなー?と思いながらもシリコンスプレーを吹いたりサラダ油を注したりと騙し騙し使っていたのですが、久しぶりにフレキシブルフィラメントを出力すると一発でNGでした。

 

ということでバレル中のPTFEチューブの耐熱260℃まで対応しているものを取り寄せました。

<詳細は画像クリック>

 

ところが、外径4mm内径2mmのこのチューブ、今使っているバレルには合いませんでした凹(使ってたバレルは外形3mmに合うタイプ)。

おそらく、このタイプ↓

<詳細は画像クリック>

 

このバレルを交換しようかとも思ったのですが、どのみち長時間同じように使っていたら同じようにチューブがヘタってくるので、もういっそのことプリントヘッドごと交換することにしました。

↓このプリントヘッドのセットであればバレルだけじゃなく、ノズルもヒートブロックもヒーターもサーミスタも全部付いてくるので万が一他が故障してもサイズが合えば交換できるよね?という発想でこちらを注文。 お値段も千円ちょいでこれだけセットならお得ですよね。

 

<詳細は画像クリック>

 

 

こちらが、新(上)旧(下)のヒートシンク+バレルを比べたものです。

f:id:DreamerDream:20181005083343p:plain

サイズは大体同じだけど、ヒートシンクの羽間隔も枚数も同じだけどが若干薄いです。

 

出力側新(上)旧(下)

f:id:DreamerDream:20181005083351p:plain

内部に使われているバレルの種類が違います。少し長いように見えます。

1mmほど長かったので最後にテーブルの高さ調整が必用でした。

 

入力側新(右)旧(左)

f:id:DreamerDream:20181005083409p:plain

使っている3Dプリンターはヘッドにエクストルーダーの部品に直付けタイプなので左の方が合っていますが、Amazonで見つけられなかったので今回はチューブ付きのタイプを購入しました。チューブを固定するねじ切りがされていて穴は邪魔なほど太すぎます。

(僕の3Dプリンターの構造は、エクストルーダーの直近までPTFEチューブを通せるのでこれで問題ありません)

 

新しいものは、このように外形4mmのPTFEチューブがズドーンと通せます。

入力からバレルまで穴径4mmです。前に購入したチューブが無駄にならずに済みそうです。

古い方は、入力側の穴が2mm程度しか開いていないので通せません。

f:id:DreamerDream:20181005083418p:plain

 

今回はヒートブロックのネジサイズが同じなのでこのヒートシンクとバレルだけ交換することにしました。

ヒートブロック、サーミスタ、ヒーター、ノズルはまた別の機会があれば交換します(サーミスタの精度は個体差があるので交換すると大幅な設定温度調整が必用になることがあります)

 

さて、古い方のバレルがどうなっているかバラしてみましょう。

f:id:DreamerDream:20181005083424p:plain

ゴム膜などで保護しながら(CDプレーヤー分解したときに出て来た防振部品)ペンチで回すとネジが傷つかず外れます。

f:id:DreamerDream:20181005083429p:plain

ヒートシンク内部も少し汚れているようです。おそらく少しフィラメントが漏れたのでしょう。

f:id:DreamerDream:20181005083435p:plain

バレル入力側、FTFEチューブは奥にひっそりと見えますがこちらからは引き出せそうにありません。

f:id:DreamerDream:20181005083439p:plain

バレル出力側から見るとPTFEチューブはかなり奥に追いやられていました。

PTFEチューブは出力側からしか外せません。

f:id:DreamerDream:20181005083445p:plain

 

 

今回の新しいバレルは上から下までズドーンと4mmなのでこのタイプ↓

<詳細は画像クリック>

 

クリップで押し出すとなんとか外れましたが、かなり摩耗している様子です。

徐々に溶けたのでしょうか?

f:id:DreamerDream:20181005083450p:plain

これではまともに出力できるハズがありませんね。

 

 

さて、図解です。

今までのエクストルーダーとプリントヘッドを図にするとこのような感じです。 

 

f:id:DreamerDream:20181005091752p:plain

上から、ピンクがエクストルーダー、緑がエクストルーダーの支え部品、黄色がヒートシンク、オレンジがバレル、水色がPTFEチューブ(バレルとノズル)、茶色がヒートブロック、赤がノズル、青がフィラメント

 

 

このプリントヘッドの構造には欠点がいくつかあります。

というか3Dプリンター自体が発展途上なので完ぺきなプリントヘッドなんてありません。

f:id:DreamerDream:20181005091801p:plain

フィラメントをエクストルーダーに通す時、入力で少し手間取ります。

赤丸の所が各部品の接合部ですので、フィラメントが引っかかる可能性のあるところです。また溶けたフィラメントが漏れるのもこの接合部です。

 

今回、バレル内のPTFEチューブが上部に追いやられていましたので、図解するとこのような型になります。

内部のチューブの途切れた箇所が広く出来てしまい押し出し抵抗が強くなり、エクストルーダーからの力が分散されてしまいます。上からの力を出来るだけ直に伝えないと押し出せない弾性フィラメントにとっては特に致命的です。

f:id:DreamerDream:20181005091811p:plain

 

で、交換した新しいものにするとこのいくつもあった部品の接合部の問題が改善されます。

溶けたフィラメントが漏れる可能性があるのはバレルとノズルの接合部だけです。

PTFEチューブをエクストルーダー近くにもっていけるのでより曲がりにくく押し出せます。エクストルーダーの部品の穴は2mm→4mmへドリルで広げました。

PTFEチューブの交換が必用な時はノズルを外して上からチューブを押し出せば簡単に交換することが出来ます。(古いものはバレル自体を取り外さないと抜けません)

f:id:DreamerDream:20181005091817p:plain

 さて、効果のほどは?

 

 

この交換のあと早速16時間の大物を出力しました。

その後でさらに1時間程度のものを追い打ちで2回出力しました。

(画像は2回目出力のもの)

f:id:DreamerDream:20181009083007p:plain

なかなか良い感じです。

 

が、残念なことにさらに1時間程度の稼動で詰まりが発生してしまいました。

計19時間程度は無問題で出力が出来ましたので前回のただシリコンスプレーを吹いただけのものよりかなり優秀だということは解りました。

で、詰まりの原因究明びためにチューブをそのまま抜いてみました。抜くのはすごく簡単!

少しフィラメントの焦げ?が出ているもののチューブ自体に損傷は無く、特に変な所で溶けている訳でも無さそうです。

(エクストルーダーの部分でフィラメントが曲がっています。)

f:id:DreamerDream:20181009083316p:plain

どこで詰まったんだろ?と観察しますと、ノズルの先端周りにベッタリとフィラメントが貼り付いてしかも焦げています。少し吐出量が多かったのかもしれません。

f:id:DreamerDream:20181009083513p:plain

余ったフィラメントがノズル周囲で固まってしまって押し出せなくなったのが原因だと思われます。

ともあれ、かなり優秀な結果に満足しましたのでコチラ↓の押し出し機、オススメ商品としておきます。

<詳細は画像クリック>

kampa.me