カテゴリー: IT

Windowsの組織や使用者をセットするPowerShellスクリプト

Windows Server 2003まではインストール時に組織と使用者が問われたが、2008から聞かれなくなった。聞かれないならいいやとも思うが、何となくセットしておきたい気もするので、後々使い回せるようPowerShell?で簡単なスクリプトを書いた。

2008 R2で確認したが、単にレジストリ変えているだけなので、Windows 7とかVistaとかでも大丈夫なはず。変更したいときもこれで良い。

スクリプト

$regPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\"

"現在の組織: "   + (Get-ItemProperty $regPath)."RegisteredOrganization"
"現在の使用者: " + (Get-ItemProperty $regPath)."RegisteredOwner"

$newOrganization = Read-Host "新しい組織を入力してください"
$newOwner        = Read-Host "新しい使用者を入力してください"

# 32ビット/64ビット共通
Set-ItemProperty $regPath -name "RegisteredOrganization" -value $newOrganization
Set-ItemProperty $regPath -name "RegisteredOwner" -value $newOwner

# 64ビットのみ
$regPath64 = $regPath -replace "SOFTWARE", "SOFTWARE\Wow6432Node"
if(Test-Path $regPath64)
{
	Set-ItemProperty $regPath64 -name "RegisteredOrganization" -value $newOrganization
	Set-ItemProperty $regPath64 -name "RegisteredOwner" -value $newOwner
}

.NETでメッセージボックスのボタンのテキストを変える

フォーム作るの面倒

メッセージボックスのボタンのテキストをちょこっと変えたいというのはありがちだができない。フォーム作るのが正攻法、でも面倒。ちょこっとだし。

フックする

Google先生いわくフックすればできるそうで。テキストの変更くらい標準でできれば嬉しいのに。

C#で書いた

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace hogehoge
{
    /// 
    /// ボタンのテキストをカスタマイズできるメッセージボックスです。
    /// 
    public class ButtonTextCustomizableMessageBox
    {
        private IntPtr hHook = IntPtr.Zero;

        /// 
        /// ボタンに表示するテキストを指定します。
        /// 
        public CustomButtonText ButtonText { get; set; }

        /// 
        /// コンストラクタ。
        /// 
        public ButtonTextCustomizableMessageBox()
        {
            this.ButtonText = new CustomButtonText();
        }

        /// 
        /// ダイアログボックスを表示します。
        /// 
        public DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icons)
        {
            try
            {
                BeginHook();
                return MessageBox.Show(text, caption, buttons, icons);
            }
            finally
            {
                EndHook();
            }
        }

        /// 
        /// フックを開始します。
        /// 
        void BeginHook()
        {
            EndHook();
            this.hHook = SetWindowsHookEx(WH_CBT, new HOOKPROC(this.HookProc), IntPtr.Zero, GetCurrentThreadId());
        }

        IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode == HCBT_ACTIVATE)
            {
                if (this.ButtonText.Abort != null) SetDlgItemText(wParam, ID_BUT_ABORT, this.ButtonText.Abort);
                if (this.ButtonText.Cancel != null) SetDlgItemText(wParam, ID_BUT_CANCEL, this.ButtonText.Cancel);
                if (this.ButtonText.Ignore != null) SetDlgItemText(wParam, ID_BUT_IGNORE, this.ButtonText.Ignore);
                if (this.ButtonText.No != null) SetDlgItemText(wParam, ID_BUT_NO, this.ButtonText.No);
                if (this.ButtonText.OK != null) SetDlgItemText(wParam, ID_BUT_OK, this.ButtonText.OK);
                if (this.ButtonText.Retry != null) SetDlgItemText(wParam, ID_BUT_RETRY, this.ButtonText.Retry);
                if (this.ButtonText.Yes != null) SetDlgItemText(wParam, ID_BUT_YES, this.ButtonText.Yes);

                EndHook();
            }

            return CallNextHookEx(this.hHook, nCode, wParam, lParam);
        }

        /// 
        /// フックを終了します。何回呼んでもOKです。
        /// 
        void EndHook()
        {
            if (this.hHook != IntPtr.Zero)
            {
                UnhookWindowsHookEx(this.hHook);
                this.hHook = IntPtr.Zero;
            }
        }

        #region メッセージのテキストのクラス定義

        public class CustomButtonText
        {
            public string OK { get; set; }
            public string Cancel { get; set; }
            public string Abort { get; set; }
            public string Retry { get; set; }
            public string Ignore { get; set; }
            public string Yes { get; set; }
            public string No { get; set; }
        }

        #endregion

        #region Win32API

        const int WH_CBT = 5;
        const int HCBT_ACTIVATE = 5;

        const int ID_BUT_OK = 1;
        const int ID_BUT_CANCEL = 2;
        const int ID_BUT_ABORT = 3;
        const int ID_BUT_RETRY = 4;
        const int ID_BUT_IGNORE = 5;
        const int ID_BUT_YES = 6;
        const int ID_BUT_NO = 7;

        private delegate IntPtr HOOKPROC(int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook, HOOKPROC lpfn, IntPtr hInstance, IntPtr threadId);

        [DllImport("user32.dll")]
        private static extern bool UnhookWindowsHookEx(IntPtr hHook);

        [DllImport("user32.dll")]
        private static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetCurrentThreadId();

        [DllImport("user32.dll", CharSet=CharSet.Auto)]
        private static extern bool SetDlgItemText(IntPtr hWnd, int nIDDlgItem, string lpString);

        #endregion
    }
}

使い方

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace hogehoge
{
    class Program
    {
        static void Main(string[] args)
        {
            var msg = new ButtonTextCustomizableMessageBox();
            msg.ButtonText.Yes = "了解";
            msg.ButtonText.No = "承知";
            msg.ButtonText.Cancel = "はい";
            msg.Show("実行してよろしいですか?", "ほげほげ", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
        }
    }
}

Raspberry PiをVPNサーバにしてAndroidから繋ぐ

2013年12月22日追記

その後、SoftEther VPNで環境を作り直しました。手順は別ページに記載しています。

やりたいこと

Raspberry PiをL2TP/IPSecなVPNサーバに仕立てて、AndroidからVPN経由で出先から自宅のネットワークに繋ぎたい。ヤマハのRTを買おうかと思ったが高いのでRaspberry PiをVPNサーバに仕立てる。

環境

  • Raspberry Pi Model B / Raspbian(wheezy)
  • ISW11K / Android 2.3.5

手順

OS入れる

使うディストリビューションはRaspbian。インストールというかddしてよしなに設定や更新する。DHCPではなく静的にIPアドレスを割り当てること。

パッケージインストール

# apt-get install lsof openswan xl2tpd

openswanがX.509証明書が云々と尋ねてくるが、よくわからんのでNoにした。証明書買うのもお金がかかるし。。。

sysctrl.conf変更

以下のような具合に追記する。

##############################################################
# VPN
net.ipv4.ip_forward=1
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.eth0.send_redirects=0
net.ipv4.conf.eth0.accept_redirects=0
net.ipv4.conf.lo.send_redirects=0
net.ipv4.conf.lo.accept_redirects=0

追記後に反映するためsysctl -pする。

# sysctl -p

openswanの設定

/etc/ipsec.conf開き、以下のように編集。めんどうなのとよくわからないのでほぼサンプルのまま。

/etc/ipsec.conf - Openswan IPsec configuration file
# This file:  /usr/share/doc/openswan/ipsec.conf-sample
#
# Manual:     ipsec.conf.5

version 2.0     # conforms to second version of ipsec.conf specification

# basic configuration
config setup
       # Do not set debug options to debug configuration issues!
       # plutodebug / klipsdebug = "all", "none" or a combation from below:
       # "raw crypt parsing emitting control klips pfkey natt x509 dpd private"
       # eg:
       # plutodebug="control parsing"
       # Again: only enable plutodebug or klipsdebug when asked by a developer
       #
       # enable to get logs per-peer
       # plutoopts="--perpeerlog"
       #
       # Enable core dumps (might require system changes, like ulimit -C)
       # This is required for abrtd to work properly
       # Note: incorrect SElinux policies might prevent pluto writing the core
       dumpdir=/var/run/pluto/
       #
       # NAT-TRAVERSAL support, see README.NAT-Traversal
       nat_traversal=yes
       # exclude networks used on server side by adding %v4:!a.b.c.0/24
       # It seems that T-Mobile in the US and Rogers/Fido in Canada are
       # using 25/8 as "private" address space on their 3G network.
       # This range has not been announced via BGP (at least upto 2010-12-21)
       virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v6:fd00::/8,%v6:fe80::/10
       # OE is now off by default. Uncomment and change to on, to enable.
       oe=off
       # which IPsec stack to use. auto will try netkey, then klips then mast
       protostack=auto
       # Use this to log to a file, or disable logging on embedded systems (like openwrt)
       #plutostderrlog=/dev/null

# Add connections here

conn L2TP
       keyingtries=0
       type=transport
       compress=yes
       authby=secret
       forceencaps=yes
       pfs=no
       auto=add
       ike=aes-sha1;modp3072
       phase2=esp
       phase2alg=aes-sha1;modp3072
       rekey=no
       salifetime=3h
       ikelifetime=1h
       left=192.168.1.20 # Raspberry PiのIPアドレスにする
       leftprotoport=17/1701
       right=%any
       rightprotoport=17/%any

さらに/etc/ipsec.secretsを編集し、事前共有鍵を設定する。

# 192.168.1.20はRaspberry PiのIPアドレス
192.168.1.20 %any: PSK "事前共有鍵とする文字列"

UTF-8で保存したら共有鍵は日本語でも接続できたが、クライアントによってハマりそうだなあ。
これで設定は終わりなのでopenswanをリスタートする。

# service ipsec restart

ベリファイをかけてFAILEDが無いことを確認。

# ipsec verify
Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path                             	[OK]
Linux Openswan U2.6.37/K3.6.11+ (netkey)
Checking for IPsec support in kernel                        	[OK]
 SAref kernel support                                       	[N/A]
 NETKEY:  Testing XFRM related proc values                  	[OK]
	[OK]
	[OK]
Checking that pluto is running                              	[OK]
 Pluto listening for IKE on udp 500                         	[OK]
 Pluto listening for NAT-T on udp 4500                      	[OK]
Checking for 'ip' command                                   	[OK]
Checking /bin/sh is not /bin/dash                           	[WARNING]
Checking for 'iptables' command                             	[OK]
Opportunistic Encryption Support                            	[DISABLED]

xl2tpdの設定

/etc/xl2tpd/xl2tpd.confを編集してxl2tpdを設定する。ip rangeは環境に応じて変更、local ipはRaspberry PiのIPアドレスにする。

[global]
port = 1701

[lns default]
ip range = 192.168.1.201 - 192.168.1.210
local ip = 192.168.1.20
length bit = yes
refuse chap = yes
require authentication = yes
pppoptfile = /etc/ppp/l2tpd.pppopt

xl2tpdをリスタートする。

# service xl2tpd restart

pppoptfileの作成

先のxl2tpd.confで指定したpppoptfile (/etc/ppp/l2tpd.pppopt)を作成する。

# vi /etc/ppp/l2tpd.pppopt

内容は以下の具合。ms-dnsにはDNSを指定する。ここではルータのIPアドレス(192.168.1.1)を指定しているが、プロバイダから指示されたDNSやGoogleのDNS(8.8.8.8)でもVPN接続時に名前解決できた。

asyncmap 0
auth
crtscts
lock
modem
debug
proxyarp
lcp-echo-interval 180
lcp-echo-failure 3

refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2

ms-dns 192.168.1.1

pppd認証の設定

/etc/ppp/chap-secretsを編集してユーザー名、パスワードを設定し、ppp認証できるようにする。

# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
UserName * Password *

ユーザー名やパスワードにダブルクォーテーションは不要。

サービス自動起動の設定

openswanとxl2tpdが自動起動するようにする。

# insserv ipsec
# insserv xl2tpd

以上でRaspberry Piの設定は終了。

ポートマッピング

ルータの設定を変更し、UDPの500番、4500番、およびESPをRaspberry PI(192.168.1.20)にマッピングする。

クライアントからのアクセス

クライアント(ISW11K)を設定し接続する。自宅のグローバルIPアドレスを調べておく。

  1. 設定→無線とネットワーク→VPN設定→VPNの追加をタップ
  2. L2TP/IPSec PSK VPNを追加をタップ
  3. VPN名を「自宅」に設定
  4. VPNサーバーの設定を自宅のグローバルIPアドレスに設定
  5. IPSec事前共有鍵の設定を/etc/ipsec.secretsで指定した文字列に設定

上記を設定して保存。

保存後、VPNの「自宅」をタップすると「自宅に接続」というダイアログが表示されるので、ユーザー名とパスワードに/etc/ppp/chap-secretsで設定した値を指定し接続する。つながらないときは、自宅のWiFi?につないでないか?と/var/log/syslogを眺めてみる。syslogに何も出てないようであれば、ルータに弾かれている可能性が大。

あとは自宅ネットワークに繋がれていることを確認(自宅サーバに繋いでもいいし、ブラウザでグローバルIPを確認できるページに繋げば自宅のIPが表示されるし)して終了。

自宅のグローバルIPアドレス

考えてみると変動するよな。固定IPじゃないし。後でDDNSサービスを設定しよう。