30代半ばの事務職員がITエンジニアになった話

おおよそタイトルのとおり、30代半ばにしてITエンジニアのタマゴになってしまった会社員の話

【MySQL】DBをOracleからMySQLへ移行する件について ~その2~

Java製アプリケーションを
別の環境でトレースするときに
オリジナルはDBがOracleだったけど
MySQLに無理やり変更してみたときの話


Auto Commitの設定


MySQLではAuto Commitがデフォルト
一方、OracleではCommitありがデフォルト
なのでOracleを前提にしたプログラムでは
TransactionやらRollbackがどうこうという
エラーがでる可能性が高い


なのでAutoCommitをOFFにする

SET autocommit=0;


検証や研究用の環境ならむしろ
AutoCommit便利だけど、本番の環境では
やっぱりCommitありのほうが安心だと思う



カラムのデフォルト制約のこと


データをインサートするとき
デフォルト値が設定してあると

CREATE TABLE AAA ( BBB int , CCC int default 0 );


例えば↑のようにテーブルを作成した場合、

insert into AAA values(1);


とインサートすると
BBBカラムに1、CCCカラムには
デフォルト値の0が入る(はず)


こともあろうにJavaのプログラムのなかで
こんな記載がされていたわけで、、


Workbenchとかで手動でSQLを書いて
データを入れ込むのであれば
CCCカラムには何も指定されてないよ!
と警告がでるだけで処理自体はされる


で、JavaでDBを使うとなると
ドライバーを使用することになるはず


現行のはOracleJDBCドライバーを
使用していてこちらは上記のSQLに対応して
問題なく使えていた


同様にMySQLJDBCドライバーを使った場合
警告がでるだけでなくException Error
つまりエラーでプログラムが中断する…


これはMySQLのドライバーのプログラムを
書いた人がそういう仕様にしたらしく
どうしようもない様子
(英文サイトを読むと多分そんな意味あい)
確かに処理としては正しいのだろうけど、、


まぁ、無償のDBを便利に使えるドライバーを
善意で提供してくれているのだから文句など
言えるはずもなく


と、いうわけで、


根本的な解決方法は
Javaのプログラムを修正するしかない


ROWIDについて


OracleにはROWIDという隠し列があり
SELECTで呼び出すことができる
中身はというとランダムにふられた
18桁の英数字で行を特定できる
早い話がキー項目


なのでMySQLでこれを実現するには
キー項目の列を作ってやればいいことになるが
問題はSQL文がプログラムに
組み込まれている場合


ROWIDを絞り込み条件にした
SELECT文なんかがあったりしたら
独自に設定したキー項目に書き換えないといけない


ちなみにOracleのROWIDは
行を削除してバックアップから戻す場合など
変わることがあるので
あまり使わないほうがいいみたい



まだ他にもいくつかあるので
また次回に

【MySQL】DBをOracleからMySQLへ移行する件について ~その1~

OracleMySQLはDBの仲間
Oracleは有料、MySQLは無料
という知識だけ持っている人が


Oracleは高いからMySQLにしようぜ」
とか言い出したため、
「そんなに簡単にいくわけないだろ!」
と思ったけど、
実際にやってみたらやっぱり
一筋縄ではいかなかった話


TimeZone(タイムゾーン)の設定


まず、TimeZoneの設定値が不正です
というエラーがでた

???? (?W????)


なんとなくJISをUTFで表示してしまったときの
文字化けに見えるので
とりあえずデータベースやテーブルなど
文字コードUTF-8にセット


しかし解消されず


実はMySQLWindowsで使う場合に、
OSにタイムゾーンが存在しないから
起こるエラーらしく
OracleMySQL移行とは関係ないんだけど
ためになったので記載しておく次第


MySQLの設定ファイル、my.iniの
[mysqld]項目に

default-time-zone='Asia/Tokyo'

を追記


このmy.iniの場所が曲者で
MySQLをインストールした場所
(C:\Program Files\Mysql\あたり)
の下にあったファイルにだまされたのだけど
正しくは「C:\ProgramData\MySQL\あたり」
にあるmy.iniファイルを編集する必要がある

データ型のちがい


このへんは真っ先に直面する課題
OracleのDBからDDLを出力して
MySQLSQLを流すと
データ型がちがうものがエラーになる


今回、ほとんどは

Varchar2 ⇒ Varchar
Number ⇒ int

でなんとかなったけど
ほぼほぼ同一のものはない様子


関数のちがい


このへんもスタンダードな課題
よく見かけるのが

NVL ( a , b  )  で
a が null なら b に置き換え

MySQLでは
Case文で対応しなければいけない
のかと思っていたけど

IfNull( a , b  )  

で代用できる


しかしNVL2は
Case文で対応するしかないのか…


VIEWで使われているだけだったので
ソースの書き換えだけで完了


MySQLにはシーケンス機能がない


OracleにあってMySQLにないもののひとつ


こともあろうにJavaプログラムのなかに
セッションのカウントとして組み込まれていた
たしかにネットでサンプルを見てても
セッションIDを振るのに使われていることが
多いので自然な成り行きかもしれない


シーケンスの機能自体はファンクションで代用

DELIMITER $
CREATE FUNCTION session() RETURNS int(8)
  DETERMINISTIC
BEGIN
  DECLARE value int(8);
  SET value = 0;
 
  SELECT id INTO value
  FROM session_id;

  UPDATE session_id
  SET id = 
  (CASE WHEN value = 99999999 THEN 1 ELSE value + 1 END);

  RETURN value + 1;
END


ただ、シーケンスの呼び出しではなく
あくまでファンクションの呼び出しなので
SQLの構文が変わる
Oracleでは空のテーブルを読み込むのに
from Dualを使うけどMySQLでは
そんな仕様はないので

SELECT SESSION_ID.SESSION FROM DUAL;
↓
select session();

と変更


実は前述の2つについては
OracleからMySQLの移行を
自動でしてくれるツールがあるらしく
おそらくそれで対応可能
便利なものがあるもんだ


しかしこのシーケンスの機能や
SQLとしてプログラムに入り込んでいる
ものはさすがに移行できないのだろう
と思う


JavaのClassファイルを逆コンパイルして
javaファイルを作りなおしたのち
Classファイルに再コンパイルして、と
その辺の話はまた別の機会に記載


長くなったので今回はここまで
続きはまた次回に

【Webサーバー】レンタルサーバーでphpをバージョンアップしたら文字化けした

相変わらず脆弱性の対応に追われている


ところどころでセキュリティの観点で
ものを見れるようになったことや
そもそも覚えることが多いので
役に立っているのはいいが


そのうち君セキュリティ担当な!
とか言われたらイヤだなぁ…


Webサーバーに文字化け発生


サーバーで使っているphpのバージョンが
古すぎる (5シリーズ) ということで
セキュリティにひっかかり、
バージョンを7シリーズまであげる
羽目になった


たしかに今になるとバージョン低いことが
リスクだと感じるようになったので
バージョンをあげるにこしたことはない


しかし、このバージョンアップにより
サーバー上の一部のhtmlに文字化けが発生


php5.5までならデフォルト文字コード
設定は"デフォルト値"が"なし"でもよく


f:id:ykk333:20191120224237p:plain
phpinfoを確認するとdefault_charsetがnot valueになっている

要するにどんな文字コードでも受け入れて
くれる設定だったということらしい


ところがphp5.6より新しいバージョンでは
デフォルト文字コードが"なし"は
許されず何かしら設定しないといけない


これもセキュリティの一環らしい
デフォルトでは"UTF-8"が設定されている


f:id:ykk333:20191119233725p:plain
phpinfoを確認するとdefault_charsetにUTF-8が指定されている


.htaccessまたはhost.conf?あたりに
以下の記述がされていると
(Apacheの場合)
拡張子が.phpのものと.htmlのものは
phpの設定が適用される


つまりUTF-8が適用される

AddHandler application/x-httpd-php .php .html


この状態で例えばhtmlファイルの
文字コードが"EUC-JP"なんかだと
文字化けが発生するというわけ


文字化けへの対策


文字化けしているhtmlのコードを見てみる

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
	<title></title>
</head>


思った通り、
meta情報がEUC-JPになっている


これをUTF-8に変えれば
楽勝だろうと思いきや


変わらない…


サクラエディタあたりの
エディタソフトで開くと


f:id:ykk333:20191120231707p:plain
文字コードEUC-JP


htmlファイルの文字コード自体が
EUC-JPで保存されていることが
確認できる


なのでこれをUTF-8に変更して
上書き保存してやると


f:id:ykk333:20191120231827p:plain
文字コードUTF-8


文字化けがなおった!


ちなみにmeta情報は変更しても
しなくても変わらず
phpinfoのdefault_charsetと
htmlファイル自体の文字コード
一致することのほうが優先されるの
だと思う


php.iniにて

default_charset = "UTF-8"

の記述があるのでこれを

default_charset = "EUC-JP"

に変えてやれば
もちろん文字コード
変更される


けど、
php5.5以下の環境で
文字コードが混在したphpファイルや
htmlファイルが存在していた場合は
どちらかに統一するしかない


ちなみに前述のとおり
デフォルトが"なし"は許されないので

;default_charset = "UTF-8"

デフォルト文字コードを指定しなかった
場合はUTF-8が設定される



php やら DB をさわっていると文字コード
ってなにかとネックになる気がする
英語圏ならこんな悩みはないのか。。


と、ちょっとだけ欧米人がうらやましい

【Windows】ファイヤーウォールのポートを閉じてリモートデスクトップで接続できない

いろいろあって、
FTPSの通信に使われているポートの
検証のためにWindowsサーバーの
ファイヤーウォールのポート
1024から65536までを閉じる設定をして
ファイヤーウォールを有効にする
ボタンを押した瞬間、

「ブツッ」

リモートデスクトップが切断される…
リモートデスクトップで使用されている
3389ポートを閉じてしまったのだから
当然だが、途方もないやっちまった感と
素人丸出し感に多少の自虐を覚える


きっと誰もが通る道だ
と言い聞かせながら解決策をさぐる

その1 net use と sc コマンド


コマンドプロンプトからサービスの
制御ができる net コマンドと
sc コマンドがあるらしい


どうやらnetコマンドは自身のみ
scコマンドはネットワークのPCの
サービスを制御できるっぽい


でもネットワーク上のPCに
ログインするためには
net use コマンドを使う
このへんはよく理解してない

まずネットワーク上のPCにadmin権限でログイン
net use \\192.168.0.10 /user:[ユーザー名] [パスワード]

PCを指定してサービスをストップ
sc \\192.168.0.10 stop mpssvc
(mpssvcはファイヤーウォールのサービス名)

ログアウトする
net use \\192.168.0.10 /delete


意外と簡単にリカバリできたじゃん
と思いきや


通信ができなくなる
pingも通らない
電源はON
つまりハングってる状態


AWSのようなクラウド環境だったので
コンソールからの再起動で
最悪の状態からは復帰できたが


しかし、原因は不明
たまたまだったのか
サービスを起動するときの
アカウントが
LocalServiceになっていることが
関係しているのだろうか…

f:id:ykk333:20190930223053p:plain
ファイヤーウォールのサービスの実行アカウント


その2 Telnet


なんとなく古風な通信方式のイメージ
しかしポートはLinuxSSHでおなじみの
22ポート、ということはわりと
何でもできるのでは?と期待大

telnet 192.168.0.10

が、事前にサーバーにTelnetをインストール
しておく必要があるらしく

NG

その3 PowerShell (WinRM)


名前はよく聞くけど実は理解していない
「今どきはbatchじゃなくてpowershell
だよな!」なんて話を聞いた
batchよりもっと複雑な処理ができる、
みたいなイメージなんだけど
合ってるだろうか


こんなかんじでリモートでbatchを起動できるようだ

PS> Invoke-Command -ComputerName 192.168.0.10 -Credential [user] {C:\test.bat}


が、これも事前にファイヤーウォール

Windows リモート管理 (HTTP 受信)

を有効にしておく必要があるらしい
しかもポートは5985…

どちらにしてもNG


その4 WMI


わりと簡単な手順とコマンドで
いろんなことができそうなサービス
以前に別のところで使ったことがあるので
いけるのではないかと思ったが

WMIC /NODE:192.168.0.10 /user:[user] /password:[pass] process call create "C:\test.bat"


これも事前にファイヤーウォール

Windows Management Instrumentation (WMI)

グループを有効化しておく必要がある


やむなくNG


その4 PsExec


Windows純正のソフトをクライアントに
入れて実行するといろいろできるらしい


が、使用するのは
135ポート
445ポート
1025~65535ポート


ということでNG


使用する場合には

PsExec.exe -u [user] -p [pass] \\192.168.0.10 C:\test.bat

のようにするみたい

その5 タスクスケジューラ


atコマンド

at \\192.168.0.10 09:00 C:\test.bat

のようなかんじで
タスクスケジューラを外部から
操作できるらしい


しかし事前にファイヤーウォール

ファイルとプリンターの共有

グループを有効化しておく必要がある
ファイルの共有自体はできていたので
グループのなかの必要な項目が
有効になっていなかったのだと思われる


atコマンドより高機能なschtasksコマンドが
あるらしい

schtasks /Create /S 192.168.0.10 /U [user] /P [pass] /TN sample /SC ONCE /SD 1900/01/01 /ST 00:00 /TR C:\test.bat
schtasks /Run /S 192.168.0.10 /U [user] /P [pass] /TN sample

のように使う

こちらもファイヤーウォール

スケジュールされたリモート タスク管理

グループを有効化しておく必要があり


やっぱりNG


しかしまだタスクスケジューラを
あきらめない、あきらめたら試合終了だ


幸いにもファイル共有はいきているので

net use \\192.168.0.10 /user:[ユーザー名] [パスワード]

でログインしたあと


エクスプローラーのアドレスバーに

\\192.168.0.10\C$

と打ち込むとサーバーの
ディレクトリが表示されて
読み込みも書き込みもできる


タスクスケジューラのタスクは
下記のフォルダにxml形式で
保存されているので
開いて中身を確認できる

C:\Windows\System32\Tasks


たまたま毎日定時に実行している
どうでもいいbatchがあった


(ちなみにここのファイルを直接編集しても
反映されずエラーになるので都合のいい
タスクがないとお手上げ)


batchファイルの最初の行に

netsh advfirewall set allprofiles state off

を追加してbatchが起動したら
ファイヤーウォールをすべて
無効化するように仕込む


これでスケジューラが起動したら
ファイヤーウォールが無効化されて
復旧完了、と翌朝ウキウキして
確認すると


batchがうごいていない…


こればっかりは謎のまま


それはともかくとして
万策が尽きてくる

その6 リモートでレジストリを変更


レジストリエディタを開き、

ファイル⇒ネットワークレジストリへの接続
"選択するオブジェクト名を選択してください"に
\\192.168.0.10を入力⇒OK

f:id:ykk333:20191002230556p:plain
レジストリエディタ


これでサーバーのレジストリを開ける


これもおそらくファイヤーウォール
リモートレジストリを受け付けるか
どうかの設定があるのだろうけど
意外にも有効になっていたらしい

\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile
\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile
\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile

がそれぞれファイヤーウォール
・パブリックプロファイル
ドメインプロファイル
・プライベートプロファイル
に相当すると思われる


それぞれの

EnableFirewallのデータ値を(0)に設定

することでファイヤーウォール
無効になる


ただし設定値を有効にするには
再起動が必要


実はいろいろあって再起動しておらず
というのは結局クラウドのコンソールから
復旧できたりしたので顛末は不明のまま



しかし、不測の事態に備えて
リモートデスクトップ以外でも
ある程度操作できるようにしておいた
ほうがいいのではと思う反面、
セキュリティホールにもなり得るので
ある意味ジレンマなのだと思う

(今回の件もどうにかして侵入して
ファイヤーウォールを無効化とか
ハッキングにも通ずる気がするし)

ともあれ
トラブルの対策がいちばん技術の
上達に役立つという話

【iOS】iPad・iPhoneでFacetimeがつながらないというか、つながるけど20秒で切れるときの対応

iPadFacetimeをつなごうとしたとき
途中で切れてしまうときの対応

事象:
Facetimeをかけるといったんつながるが、19秒経つと突然強制的に通話が切断される


そもそもつながらないとかいう事象は
ググるとけっこうでてくるけど
上記の対応は見つけられなかった

原因究明までの道のり


我が家で以前使っていたおさがりのiPad2
義母に預け使用している

義母からFacetimeで通話ができないと
相談を受ける

内容はいったんつながるけどすぐ切れる
通話相手は我が家ともうひとり

ここであやしいと思われるのは
iPad本体か回線

我が家にiPadを持ってきてもらい検証

同一LAN内でiPad2から我が家のiPad Air2に
Facetimeしてみる

結果はいったんつながるものの
19秒経過すると切断される

ここでハードの問題と特定し
古い筐体であることから
Facetimeの再インストール
iOSをギリギリまでアップデート
iPadの再起動など
考えらえることをすべて試す

が、状況変わらず

そのままお帰りいただくが
後日、義母宅からもう一方とは
Facetimeできたとの連絡

しかし、我が家との通信は
相変わらず途中で切断

ここで我が家の回線を疑う

我が家から別のiOSユーザーに
Facetimeしてみる

結果、同じように途中で切断される

この時点では回線状況と特定
いつ買ったかもあまり覚えていない
古い安物のルーター
こいつに疑いの目を向ける

今回iPadということで
有線と無線の切り分けはできない
ルーターの設定画面から設定項目を
見てみるも関係ありそうなものは
見当たらない

しばらく悩んだ末、
そもそも回線が原因ではないのでは?
と頭を切り替える

我が家のはまだまだ新しい機種という
先入観と(実際はそんなに新しくもないが)
これまでの経緯により除外していたが

Facetimeの再インストールと
iPadの再起動を実施
おそらく効果があったのは再起動のほう

なんなくつながるようになる…

教訓


障害が起こった際の切り分けは有効だけど
そこで除外したからと言って
すべて可能性なしとするのではなく
結果が行き詰った際には頭を切り替えて
もう一度疑ってみることが大切


不具合が起こっている原因として
あり得るものはすべて試してみること


というか後から考えると原因が我が家の
iPad本体にあったことに気づくチャンスは
けっこうあったことに気づく


もうひとつ
パソコンとちがいスマホタブレットって
意外と再起動していないことに気づく


昔からトラブルの7割は再起動で治ると
言われている(?)ようにまずはこれ


トラブルじゃなくても
キャッシュのクリアや更新などなど
感覚的にたまには再起動してあげたほうが
何かといい結果を生むんじゃないかという
気がする


余談:

なんで19秒で切れるのかは結局不明だけど
よくあるアプリの設定画面で通話をかけた
際のタイムアウト設定等々を探すも
そもそも設定画面らしい画面が見当たらない


iOSのコンセプトとして
シンプルに誰でも直感的に使えるように
という配慮なのだと思うが
いろいろ設定をいじってみたくなる
衝動にかられるタイプの人間には
物足りなく感じてしまう今日この頃

【Webサーバー(IIS)】CookieにSecure属性を設定する

CookieにSecure属性がついていないという
脆弱性の指摘を受けたのでその対策


今回の環境はWebサーバーがIIS
APサーバーがtomcatという構成


tomcat側でもSecure属性の設定は
できるんだけど、サイトの構成上
httpとhttpsが混在している場合、
Cookieの情報を見にいったりしてると
うまく動かないことがあるので


アプリケーションの外側で動いていて
やりとりをオーバーラップしているような
Webサーバー側で設定してあげるのが
正解らしい


というわけで今回はIISへ設定


IISでの設定方法


設定するにはURL書き換えから設定するか
web.configの記載を修正する


GUIが売りのIISの場合、
たいがいのことはアイコンから
設定でき、その操作が
自動的にweb.configに記述されるので
ほとんどの操作はいちいちweb.configを
書き換える必要はないが敢えて


web.configと一言で言っても
IIS全体のマスター?configと
その下位に位置するサイトごとの
web.configが存在し、
通常はサイトごとのほうを編集する
サイト名を右クリックしてフォルダを開く


f:id:ykk333:20190703230931p:plain
IIS フォルダを開く


f:id:ykk333:20190703223920p:plain
IIS フォルダを開く


web.configが見当たらない場合は
なんでもいいので設定をすれば
自動的にweb.configが作成されるらしい


web.configを開いたら

以下の通り設定を記載する

<configuration>
  <system.webServer>
        <rewrite>
            <outboundRules>
                <rule name="cookie secure">
                    <match serverVariable="RESPONSE_SET_COOKIE" pattern=".*" ignoreCase="false" />
                    <action type="Rewrite" value="{R:0}; secure" />
                </rule>
            </outboundRules>
</configuration>


writeはURL書き換え
outboundRulesは出る側の通信のルール
"リクエストのあったすべてのファイルに
対するCookieの末尾にsecureをつけなさい"
という記述


前回の記事でも書いたとおり
セキュリティ上の脆弱性ということで
たびたび指摘される件だけど
これを設定することで完璧!というよりも
やらないよりやったほうがいいよね
くらいのもの


しかしながらセキュリティは高すぎるから
困るということはないものなので
設定しておくにこしたことはない

【セキュリティ】CookieのSecure属性について詳しく調べてみる

CookieにSecure属性がついてないという
ありがたーい脆弱性の指摘を受けた


Secur属性とは何かと言うと、

https通信じゃないとCookieを発行しない

というものらしい
暗号化されていないhttp通信で
Cookieでよく使われるセッションID
なんかが漏えいしたら
セッションを乗っ取られて
やりたい放題されるということかと

http通信下でのCookie secure属性の検証


いろんなサイトを読むと
httpsじゃないとCookieを発行しない
とあるので検証してみる


まずはhttpでsecure属性なし

f:id:ykk333:20190821231228p:plain
http secureなし httpヘッダー

当然Cookie情報が表示される


続いてhttpでsecure属性あり
上記の理論通りなら
Cookie情報が表示されないはず



f:id:ykk333:20190821231652p:plain
http secureあり httpヘッダー

思いっきり表示されてんじゃん…
(secure属性がついていることは確認できる)


待てよ、ブラウザ上は表示されてるけど
通信上ではちゃんと隠されてるのでは?
ということでパケットキャプチャを確認


f:id:ykk333:20190821232211p:plain
http secureあり パケットキャプチャ


ちゃんと表示されている


そりゃそうだ


Apacheの設定(検証にはApacheを使用)
が間違っているのかとかなり当惑したが


調べたところ、
secure属性があると
http通信のときは

Cookieをブラウザに保存しない

という挙動になるらしい


本当にCookieが保存されないのか検証


まずはhttpでsecure属性なしの場合

f:id:ykk333:20190821233204p:plain
http secureなし cookie情報

しっかりCookieがブラウザに保存されてる


続いてhttpでsecure属性ありの場合

f:id:ykk333:20190821233323p:plain
http secureあり cookie情報

Cookieが保存されていないことを確認


つまり正確に言うと

http通信でsecure属性があると
secure属性つきでcookieは発行されるが
ブラウザには保存されない

ということになる

考察、というか疑問


で、これの悪用のしかたはというと


・偽サイトを用意して脆弱性のある
サイトへのリンクを踏ませて
Cookieを搾取


・アクセスポイントを偽造するなどして
流れてくるCookieを搾取


…つまり通信上のCookieを盗聴してる
わけだから、被害者のブラウザに
Cookieが保存されようがされまいが
どっちでもよくて
Secure属性がついてたとしても
盗聴されるのは上記の通り


Secureどうこうよりも
通信が暗号化されているかどうかの
ほうが重要で、
・httpでのアクセスを受け付けない
・サイト内にhttp・httpsを混在させず
すべてhttpsに統一
といったことのほうが大事なんだと思う


それでもブラウザにCookieが保存されるか
されないかの違いはあるので
設定しておいたほうがいいんじゃない?
くらいのものだと認識している


大いに勘違いしているかもしれないので
間違っていたら誰か指摘してください[]