わたしの日記だよ

ー生きる厳しさと哀しさを鮮烈に謳うー

【VirtualBox】ホストOSからゲストOSへ、Web接続出来ないときに確認すること

久しぶりに、開発環境を作っていて、ハマってしまいました。

 

今回使用した環境は

・CentOS7

・nginx

です。

 

ネットワーク設定と、nginxのインストール・設定を終えたところからスタートです。

 

①ゲストOSからWebページを表示する

 ゲストOSで、「curl localhost/index.html」などして、ページが返ってくるか見ます。

 →ページが返ってこなければ、nginxが起動しているか、confファイルの設定が

間違っていないかを見直します。

 

 

②ゲストOSへping or ssh接続を行う

 →もし、接続不可であれば、ホストオンリーアダプタの設定が間違っているのかもしれません。

 私は、nmtui→TUI画面でホストオンリーアダプタのIPアドレスを指定するときに

 サブネットマスクを指定し忘れることが多いです。

 VirtualBoxでは、特に設定を変えていなければ、サブネットマスクは、「255.255.255.0」

 だと思いますが、CentOS7では未指定だとデフォルトで「/32」が設定されるようです。

 ので「255.255.255.0」に対応した「/24」を指定します。

 

 もし、ホストオンリーアダプタの設定を見直して問題がなければ、③へ

 

 

③ゲストOSのSELinux設定

 getenforce で「Enforcing」と返ってきたら、SELinuxが起動しています。

 個人の環境であれば、セキュリティレベルを下げる(無効か、違反があってもログだけ出して通す)

 のが手っ取り早いです。

 sudo vi /etc/selinux/config して

      1 
      2 # This file controls the state of SELinux on the system.
      3 # SELINUX= can take one of these three values:
      4 #     enforcing - SELinux security policy is enforced.
      5 #     permissive - SELinux prints warnings instead of enforcing.
      6 #     disabled - No SELinux policy is loaded.
      7 SELINUX=enforcing
      8 # SELINUXTYPE= can take one of three two values:
      9 #     targeted - Targeted processes are protected,
     10 #     minimum - Modification of targeted policy. Only selected processes  are protected.
     11 #     mls - Multi Level Security protection.
     12 SELINUXTYPE=targeted
     13 
     14 

 

 7行目の「SELINUX=enforcing」のところを

  無効…「SELINUX=disabled」

  または

  違反時ログのみ…「SELINUX=permissive」

 に変更して、ゲストOSを再起動します。

 

 本当は、ちゃんとターゲットの設定とかで対応したいところです。

 早いところ、SELinux入門しなくては。。

 

 

 

④ ゲストOSのfirewalldの設定

  firewalld も、まずは起動を確認します。

  systemctl status firewalld で runnig と返ってきたら、起動中です。

  こちらも、個人の環境ならOFFにしてしまってもよいです。

  http、httpsを許可する手順は以下です。

 

  (1)許可されているサービスを確認

    sudo firewall-cmd --list-all すると、ネットワークゾーンに対して

    許可されているサービスを確認できます。

    私の環境では、以下のようになっていました。

 public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3 enp0s8
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  sourceports: 
  icmp-blocks: 
  rich rules:

 

   一番上が、ネットワークゾーン名です(「public」は公開用のネットワークゾーン)。

   servicesの項目にある、「dhcpv6-client ssh」のみが許可されています。

 

  (2)http、httpsを永続的に許可する

   sudo firewall-cmd --permanent --add-service=XXX(追加したいサービス)

   を実行します。

   逆に、許可を取り消したいときは、--add-serviceのところを、--remove-serviceで実行します。

   許可の変更が全て終わったら

   sudo firewall-cmd --reload します。

   再度、(1)の確認を行い、変更が反映されていることを確認して完了。

 

 

 

ここまできたら、Web接続できるようになってるはず!

 

 

 

Remote Desktop for Mac で共有フォルダを設定する

最初、環境設定から設定すると思って、ちょっと探してしまったのでメモ。

 

 

◯共有フォルダを設定したい接続情報のコンテキストメニューから、「Edit」を開く

f:id:s31o3:20170420111236p:plain

 

 

◯[Redirection]タブ - 「Enable folder redirection」にチェックを入れて

 追加ボタン(+)を押下

f:id:s31o3:20170420111226p:plain

 

◯任意のパスを指定するだけ

f:id:s31o3:20170420111642p:plain

 

 

…リモート側のディレクトリはどこに設定するの!?と思っていたら

エクスプローラーのナビゲーションウィンドウに、上で指定したディレクトリが

表示されるのでした。

AzureのSSLサーバ証明書設定

先日、作業したのでメモ。

ローカル環境はMacです。

 

1.CSRの用意

 ◯Remote Desktop for Macで、Azureへログイン

  

Microsoft Remote Desktop

Microsoft Remote Desktop

 

 ◯[サーバーマネージャー]-[ツール]から「インターネットインフォメーションサービス(IIS)マネージャー」を選択

 

 ホームから、「サーバー証明書」を開く

f:id:s31o3:20170419135153p:plain

 

つづいて、[操作]-[証明書の要求の作成]を選択

f:id:s31o3:20170419135514p:plain

 

以下を入力(全項目必須)

f:id:s31o3:20170419135759p:plain

 

次のページで

 ・暗号化サービス プロバイダ:「Microsoft RSA〜略」

 ・ビット長:2048

を指定して次へ。任意のパスを指定して、csrファイルを作成。

 

2.アクティベート

 SSLを購入したところの管理画面から、SSL証明書のアクティベートをする。

 CSRの項目に、1.で作成したCSRファイルの中身をコピペする。(あとは、英語表記で会社の住所等を設定するだけ)

 

 今回、SSLを購入したところ(ニジモ https://www.ssl-store.jp/ )では

アクティベート後、指定したメールアドレス宛に中間証明書が送られてくる。

 メール本文の

-----BEGIN CERTIFICATE-----
〜〜略
-----END CERTIFICATE-----

 までを、ファイル名に、拡張子「.cer」指定して保存。

 

3.中間証明書インポート

 再び、リモートデスクトップでAzureに接続。

 今度は、「証明書の要求の完了」を選択。

f:id:s31o3:20170419141848p:plain

 

以下を設定する

・証明書機関の応答が含まれるファイルの名前:2.で保存したファイル(.cer)

・フレンドリ名:任意の名前(管理するときにわかりやすい名前)

・新しい証明書の証明書ストア:個人

f:id:s31o3:20170419142310p:plain

 

インポートを完了してサーバー証明書の一覧へ戻ると、作成した証明書が表示される。

念のため、内容を確認。(該当証明書をダブルクリック)

f:id:s31o3:20170419142749p:plain

 

 [詳細]タブを開いて、以下の値が合っているかチェック。

 ・有効機関の終了

 ・[サブジェクト]-[CN(common name:ドメイン名)]

f:id:s31o3:20170419143308p:plain

 

 

4.SSL証明書エクスポート

 IISマネージャーの該当証明書レコードのコンテキストメニューから、

「エクスポート」を選択。

f:id:s31o3:20170419143535p:plain

 

・エクスポート先

・パスワード

に任意の値を入れてOK

f:id:s31o3:20170419144003p:plain

 

 

 

5.サーバー証明書アップロード

 Azureの管理画面で

 [App Service]-[設定]-[SSL証明書]-[証明書のアップロード]を選択 

 

 

 以下を指定してアップロード

 ・PFX証明書ファイル:4.で作成したファイル

 ・証明書のパスワード:4.で指定したパスワード

 

 

 

6.SSLバインド

 [App Service]-[設定]-[SSL証明書]-[バインディングの追加]を選択

 

f:id:s31o3:20170419145516p:plain

 

 以下を指定して[バインディングの追加]を押下

 ・ホスト名:証明書作成時に指定したドメイン

 ・証明書:5.でアップロードした証明書

 ・SSLの種類:SNI SSL

f:id:s31o3:20170419145856p:plain

 

 

完了!

 

数分すれば、SSL証明書が適用されます。

VirtualBox + CentOS6 ホストオンリーアダプターの設定

会社のプロジェクトが大炎上したり、第一子をリリースしたりしていたら

前回の投稿から1年以上経っていました。

時の経つのは、ほんとうにあっという間ですね。。。

 

最近、ちょっとしたお手伝い作業で環境構築をしているので、色々メモしていきたいと思います。

子の世話しかしてなかったので、何もかも忘れ去ってしまった。

…というか、ど忘れに次ぐど忘れが認知症を疑うレベルで、恐怖におののいています。。。

1.準備

 ◯CentOS6の仮想環境を作る

  isoファイルはこちらから↓↓↓。minimal.isoってやつです。

  Index of /pub/Linux/CentOS/6.8/isos/x86_64

 

2.設定

  VirtualBoxマネージャーから、[設定] - [ネットワーク] - [アダプター2]を開いて

  ・割り当て:ホストオンリーアダプター

  ・名前:vboxnet0

  を設定。

  ※ [MACアドレス] の値を後で使うのでメモっておきます(①)。

f:id:s31o3:20160630092634p:plain

  続いて、VirtualBox の [環境設定] - [ネットワーク] - [ホストオンリーネットワーク] から

  vboxnet0 を開きます。

f:id:s31o3:20160630093659p:plain

  [アダプター] - [IPv4アドレス] の値もメモりましょう(②)。

f:id:s31o3:20160630093733p:plain

  

  ここからは、ゲストOSにログインして作業します。

$ cd /etc/sysconfig/network-scripts
$ vi ifcfg-eth1

 

   ifcfg-eth1 ファイルの中身は↓↓↓こんなかんじ。

DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
HWADDR=08:00:27:9D:62:60
IPADDR=192.168.33.2
NETMASK=255.255.255.0
NETWORK=192.168.33.0

  HWADDRには、 ①の値(2文字ずつ、「:」区切りで)

  IPADDRには、②の値の末尾を任意の値に変えたもの

  NETWORKには、②の値を入れます。

 

 

  ネットワークを起動。

$ ./ifup eth1

 

 

2.確認

  ホストOSから pingssh 接続をしてみてつながればOKです。

$ ssh root@192.168.33.2

 

 

 

 

 

JavaScriptで<input type="file">で選択されたファイルサイズを取得する〜IE編〜

先日作った、画像ファイルが選択されたら、ファイルアップロードを行う処理↓↓

struts+jQuery Form Pluginを使ったファイルアップロード① - わたしの日記だよ

ですが、JavaScriptでファイルサイズをチェックする処理を入れていたものの

IE8だとチェックが効かないよ!と言われてしまいました。

 

1.現在の実装

今のjsファイルはこんな感じ。(赤字の部分です)

fileupload = function(event) {
  var $form, target;
  target = event.target ? event.target : event.srcElement;
  $form = $(target).closest('form');

  return $form.ajaxSubmit({
    'target': "body",
    'cache': false,
    'beforeSubmit': function(formData, jqForm, options) {
      // ファイルサイズチェックなどの処理
      for (var i = 0; i < formData.length; i++) {
        if (formData[i]["name"] == "imgFile") {
	  var file = formData[i]["value"];
          if (file.size > 200000) {
	    alert("画像は200KB以内のファイルを選択してください。");
	    return false;
	  }
        }
} }, 'success': function(filename) { // アップロード成功時の処理 alert("success"); } }); };

 jsp側は、前回のエントリ参照。と言っても、ただformの中にtype="file" name="imgFile"のinputタグがあるだけです。

 

上記のコードだと、File APIに対応しているブラウザでないとダメなのですね。

こちら↓↓によると、IEだと対応しているのは10以降。

JavaScriptでローカルファイルを自在に操る - File API | Think IT(シンクイット)

 

2.回避策・・・imgオブジェクトを使用して取得する

こんなページを見つけました。

任意のファイルのファイルサイズを取得する

選択されたファイルを、一度imgオブジェクトにセットするとサイズが取得できるらしい!

↑↑のページでは、画面に実際にちいさーく表示されるimgを置いていたのですが

なるべく余計な要素を追加したくないので、newしてなんとかならないか、試してみます。

変更後のjsはこんな感じ。

(赤字だった部分だけ。「formname」部分は実際のformのname属性です)

  // File APIチェック
  if (window.File) {
    // File API対応
    var file = formData[i]["value"];
  } else {
    // File API非対応
    var file = new Image();
    file.src = document.formname.imgFile.value;
  }
  alert("file size=" + file.size);

結果は△でした。

type='file'のvalueプロパティには、セキュリティ上の理由により制約が設けられていて

「document.formname.imgFile.value」で取れるパスは

f:id:s31o3:20150414114941p:plain

こんな風に途中がダミーになってしまいます。

該当のサイトを信用済みサイトに登録すれば、本物のパスを取得できるようになりますが

お客さんにそんなこと言えないので実質×ですね。。。><

 

この後、画面にimgタグを置くパターンも試してみましたが、同じ結果になってしまいました。

リンク先のページをIE8で開いた場合は、取得できるのに何で!?

 

今回は、時間の都合でphp側でチェックするように切り替えちゃいますが

また追って調査したいと思います。

 

 

 

 

 

 

Xcode6+swift アプリのディレクトリ構成とディレクトリパスの取得

アプリに同梱した画像のzipファイルを、初回起動時に解凍する処理を作っています。

iOSのときは、同梱するファイルや解凍したファイル、どこに置くんだっけ?と思ったので調べてみました。

ついでに、各ディレクトリパスの取得方法も。

 

1.ディレクトリ構成について

いきなり、わかりやすいまとめがありました。

参考:今こそ復習したい、iOSアプリのディレクトリ構成 - Qiita

・zipファイル・・・MyApp.app/(普通の画像と同じ扱い)

・解凍したファイル・・・Library/

に置けば良さそうです。

 

2.各ディレクトリパス取得方法

主なディレクトリパスの取得方法は、MyApp.app/、tmp/、その他のディレクトリ

で分かれています。

 

①MyApp.app/

NSHomeDirectory()

 

②tmp/

NSTemporaryDirectory()

 

③その他は、NSSearchPathForDirectoriesInDomains() メソッドか、NSFileManagerクラスの

URLsForDirectory() または URLForDirectory()メソッドで取得します。

NSFileManagerのほうを検討するように、とあったので、今回はそちらを使用します。

参考:Foundation Functions Reference

URLsForDirectory(directory:NSSearchPathDirectory, 
inDomains domainMask:NSSearchPathDomainMask) -> [AnyObject]

URLForDirectory(directory:NSSearchPathDirectory,
inDomain domain:NSSeatchPathDomainMask,
appropriateForURL url:NSURL?,
create shouldCreate:Bool,
error error:NSErrorPointer) -> NSURL?

 

パラメータ名役割
directory検索したいディレクトリ。NSSearchPathDirectoryを使って指定。
domain検索したい場所。NSSearchPathDomainMaskを使って指定。
urldirectoryにNSItemReplacementDirectory、domainにNSUserDomainMaskが指定されているとき以外は、無視される何か。(わたしの理解力の限界)
shouldCreateディレクトリが存在しなかった場合、作成するかどうか。trueで作成する。
errorエラー情報用のポインタ

 

どちらのメソッドもだいたい一緒ですが

・URLsForDirectoryは戻りが配列になっていること

・URLForDirectoryのほうは、戻りがひとつなので、複数の場所を指定するdomain(NSAllDomainMask)は使えないこと

がポイントかなと思います。

 

使い方は、こんな感じ。

        // MyApp.app/
        let homeDir = NSHomeDirectory()
        println("homeDir: \(homeDir)")
        
        // tmp/
        let tmpDir = NSTemporaryDirectory()
        println("tmpDir: \(tmpDir)")
        
        // NSFileManager取得
        var mgr = NSFileManager.defaultManager()
        
        // Documents/
        let documentDir:AnyObject = mgr.URLsForDirectory(.DocumentDirectory,
            inDomains: .UserDomainMask)[0]
        println("documentDir: \(documentDir)")
        
        // Library/ ディレクトリがなかったら作成する、エラー情報は使用しない
        let libraryDir = mgr.URLForDirectory(.LibraryDirectory,
            inDomain: .UserDomainMask,
            appropriateForURL: nil,
            create: true,
            error: nil)
        println("libraryDir: \(libraryDir)")
        
        // Library/Caches ディレクトリがなかったら作成しない、エラー情報を使用する
        var error:NSError?
        let cachesDir = mgr.URLForDirectory(.CachesDirectory,
            inDomain: .UserDomainMask,
            appropriateForURL: nil,
            create: false,
            error: &error)
        println("cachesDir: \(cachesDir)")
        
        if (error != nil) {
            println("error: \(error)")
        }

 

そして、実行結果はこんな感じでした。

homeDir: /Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]
tmpDir: /Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]/tmp/
documentDir: [file:///Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]/Documents/]
libraryDir: Optional(file:///Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]/Library/)
cachesDir: Optional(file:///Users/[user name]/Library/Developer/CoreSimulator/Devices/[device ID]/data/Containers/Data/Application/[App ID]/Library/Caches/)

 

NSSearchPathDirectoryの値は、上記以外にもPicturesDirectory(~/Pictures)とか

使いそうなものがたくさんありました。

やっぱり、Reference読むのが一番ですね。

 

 

Xcodeのグループと、実際のディレクトリ構成を合わせるツール Synx

以前、一度だけiOSのプロジェクトに入ったことがあるのですが

Xcode上でせっせとグループ分けをしたのに、実際のファイルはプロジェクト名のディレクトリ直下に

ばーっと入っていて、とてもびっくりしました。

 

それ以来、個人でアプリを作るときは、グループ作ったらディレクトリも作って・・・と

気をつけていたものの、気を抜くと忘れちゃう。

 

Synxはコマンドひとつで、Xcodeプロジェクト上のグループに実際のディレクトリ構成を

合わせてくれる便利ツールです。

 

1.インストール

ターミナルから

$ gem install synx

おわりー!!

 

2.使い方

使い方もとっても簡単です。

$ synx [プロジェクトファイルのパス(XX/XXX/XXX.xcodeproj)]

※cocoapodsを使用している場合は、上記コマンドの後に

$ pod install

したほうが良いようです。

(私の環境では、しなくても大丈夫でした)

 

もし、pod install してもうまく動かなくなってしまった場合は、一度pod関係を削除してからsynxするのが良いようです。

参考:cocoapods使用環境でsynxすると動かなくなる - Qiita

 

3.オプション

オプション役割
--prune, -pXcodeプロジェクトから参照されていないソースファイルと画像ファイルを削除
--no-colorログ出力をカラーにしない(指定しないと色分けして出力されます)
--no-default-exclusionsデフォルトの除外(/Libraries、/Frameworks、/Products)を使用しない
--quiet, -qログを出力しない
--exclusion, -e対象外のディレクトリを指定する

 -p、-eあたりはよく使いそうです。