Samba Active DirectoryへのLDAPによるユーザ追加
こんにちは。
機械音痴の鯖防人です。
先日、自身が所属する研究室のメンバーを管理する、ADをSambaを使って立てました。
今回はそのことについて、ちょっとお話ししようかと思います。
以前はOpenLDAPを使っていたのですが、RADIUS連携する際にパスワードの扱いにちょっと困ってしまったので
研究室の認証基盤の不調を機に、構築し直すことにしました。
OpenLDAPの構築事例を見ると、SSHAを使っている場合が多いのですが
SSHAはハッシュなので、RADIUSとかで使うときに困ります。(困りました)
そのため、以前は、アカウント登録の際に、LDAPとRADIUS(RDBバックエンド)両方に登録を行うという
非常~に頭の弱いやり方を採用していました。。
RADIUSを前提としたOpenLDAPの構築事例は無いのかと探してみれば、
LDAPにパスワードを平文で登録していて「おいおい…」となりました。
この辺実運用ではどうやってるんですかね…
(まぁ社内システムとかでOpenLDAP&FreeRADIUS使ってるなんてことは無いか…)
と、いうわけで
これを解決するために、Active Directoryを構築することにしました。
SambaでADを構築すれば、タダです。
なお、Samba Active Directoryの構築・設定の仕方は、ここでは説明しません。
このページなどを参考にしてもらえればいいと思います。
www.rem-system.com
それでは本題。
Samba Active Directoryを扱っている事例はそこそこあったのですが、
LDAPでユーザ追加する方法を紹介しているサイトがあまりなかったので
備忘録的に書いておきます。
通常、LDAPは、認証などはTLSを使わずに行うことが多いのですが
Sambaの場合、LDAPS強制でした。
(ここを、面倒だと思うか、安全で良いと思うか)
ですので、Samba ADにLDAPで接続するときは、LDAPSを使います。
ldaps://hogehoge で大丈夫です。
次に、ユーザアカウントの属性ですが、
基本Windows Serverに従っているので、それを参考にしたら良いんだと思いますが
docs.microsoft.com
今回は、以下のような属性にしました。
属性名 |
値 |
---|---|
objectClass |
top |
objectClass |
person |
objectClass |
organizationalPerson |
objectClass |
user |
sn |
Doe(苗字) |
cn |
10001(コモンネーム(社員番号など)) |
instanceType |
4 |
objectCategory |
CN=Person,CN=Schema,CN=Configuration,DC=test,DC=local |
displayName |
John Doe(表示名(氏名など)) |
sAMAccountName |
10001(cnと同じ) |
userPrincipalName |
10001@test.local |
userAccountControl |
512 ※1 |
distinguishedName |
CN=10001,CN=Users,DC=test,DC=local |
uid |
10001 |
homeDirectory |
/home/10001 |
loginShell |
/bin/bash |
uidNumber |
10001 |
gidNumber |
10001 |
unicodePwd |
※2 |
基本的に512を指定します。512は一般的なアカウントを示します。
https://support.microsoft.com/ja-jp/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties
※2
パスワードをダブルクォーテーションで括った文字列を、UTF-16LEでエンコードしたものです。
[MS-ADTS]: unicodePwd | Microsoft Docs
実運用の場合でも、だいたいこれくらいの属性情報になるのではないかと思います。
そして、ユーザ追加のフォームですが
phpで以下のように書いてみました。
良かったら参考にしてみてください。
<?php if(!empty($_POST['submit'])) { $ds = ldap_connect("ldaps://localhost"); if($ds) { ldap_set_option($ds,LDAP_OPT_PROTOCOL_VERSION,3); $r = ldap_bind($ds,"cn=Administrator,cn=Users,dc=test,dc=local","ぱすわーど"); $dn = "cn=" . $_POST['uid'] . ",cn=Users,dc=test,dc=local"; $info["objectClass"][0] = "top"; $info["objectClass"][1] = "person"; $info["objectClass"][2] = "organizationalPerson"; $info["objectClass"][3] = "user"; $info["sn"] = $_POST['sn']; $info["cn"] = $_POST['uid']; $info["instanceType"] = "4"; $info["objectCategory"] = "CN=Person,CN=Schema,CN=Configuration,DC=test,DC=local"; $info["uid"] = $_POST['uid']; $info["displayName"] = $_POST['cn']; $info["sAMAccountName"] = $_POST['uid']; $info["userPrincipalName"] = $_POST['uid'] . "@test.local"; $info["userAccountControl"] = "512"; $info["distinguishedName"] = $dn; $info["homeDirectory"] = "/home/".$info["uid"]; $info["loginShell"] = "/bin/bash"; exec("ldapsearch -x -H ldaps://localhost -D cn=Administrator,cn=Users,dc=test,dc=local -w ぱすわーど -b cn=Users,dc=test,dc=local -LLL | grep uidNumber: | cut -f 2 -d ' ' | sort -nr | head -n 1",$uidNum,$res); $uid = ++$uidNum[0]; if($uid <= 1000) { $uid = 1001; } $info["uidNumber"] = $uid; $info["gidNumber"] = $uid; $info["unicodePwd"] = mb_convert_encoding("\"" . $_POST['password'] . "\"", "UTF-16LE"); $r = ldap_add($ds,$dn,$info); if($r === FALSE) { echo "LDAPサーバへの登録に失敗しました<BR>"; } else { echo "LDAPサーバへの登録完了しました<BR>"; } ldap_close($ds); } else { echo "LDAPサーバへの接続に失敗しました"; } } ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>ADアカウント登録</title> </head> <body> <h2>ADアカウント登録</h2> <form method="post" action=""> <table> <tr> <th>社員番号</th> <td><input type="text" name="uid"></td> </tr> <tr> <th>Family Name</th> <td><input type="text" name="sn"></td> </tr> <tr> <th>Name(例:John Doe)</th> <td><input type="text" name="cn"></td> </tr> <tr> <th>Password</th> <td><input type="password" name="password"></td> </tr> <tr> <td><input type="submit" name="submit" value="送信"></td> </tr> </table> </form> </body> </html>
以上です。
ほかにも、ADからデータ取ってきてRADIUSに渡して無線LANの認証したり、
いろいろやったんですが
気が向いたら、鯖防人が忘れないように、書いておくかもしれません。
では。