Wednesday, June 23, 2010

无线网络配置

总是有一种怪感觉: 不能太依赖GUI程序。
在我的记忆中, 还是存在着一种场面:系统无法正常进入X而无法正常使用linux的痛苦记忆。总是感觉GUI是学习使用linux的拦路虎。
所以一般情况下, 我都是CLI程序行先的。这也是防止出现我很不喜欢的感觉。

网络照样是CLI行先。之前我的router是配置成WEP的, 都是使用wireless-tools工具集可以很好处理。 但是慢慢地, 这种加密网络已经被淘汰了。 WEP逐渐出的时, WPA流行起来,同时linux也产生了新的一套wireless配置机制:nl80211.  这是为什么wireless-tools工具集无法使用WPA网络的原因
使用WPA无线现在一般是使用wpa_supplicant工具

使用CLI工具最烦就是需要多手动。 复杂的工具还需要配置文件。

其实这都是一次性的, 因为有脚本的存在。

我也是一个懒人~~~谁都不想每次都搞十几钟才上得了网。命令还是比较好办, 就麻烦的是配置文件, wpa_supplicant的配置文件也不是省油的。

特别是在没网络,不能google的时候更是无奈。 对!这种“无奈”是我最不喜欢看到的! 我很讨厌这种感觉。

相信解决的方法是一定会存在的~~~~

“就地出材”是一条出路, 即:不联网也可配置wpa_supplicant!
copy是方法, How ? 从wpa_supplicant的man里copy出可使用的配置文件来。
在man 5 wpa_supplicant里看到: Catch all example that allows more or less all configuration modes.

这个问题已经解决了, 不存在是否有google。也不存在是否有Networking-manager。 (可以直奔可爱的gentoo世界)
把配置copy出来, 按实现情况修改, 去掉不用的, psk使用wpa_passphrase得到。 一切都是没有问题的
* 如果这一步无法做到, 还是去使用GUI吧, 或者是思考一下问题出在哪里。

============= 华丽的分隔线 ===================

下面是N久在docs里存放的文字, 随便一起放出:

计算机的网络是最常见的配置了。来到北京这边。朋友的宿舍里的网络和广东的不一样:
1. 一个宿舍只有几台计算机上网。
2. 可以上网的机器都被登记MAC地址。
3. 可以上网的机器都分有固定的IP, netmask, DNS, gateway
4. 需要web登陆认证方可使用网络。
5. WEP方式

其实就是MAC的限制 + web登陆认证。

还是很管用的。 至少市场卖的路由没有针对这一系统的web登陆。

为了自己的机器可以上网。只需要满足上面的条件即可。 
针对于有线的情况:

ifconfig eth1 hw ether 00:1e:65:18:e2:a8
ifconfig eth1 10.3.52.132 netmask 255.255.255.0
route add default gw 10.3.52.1

然后使用browser访问web认证即可。

有线的倒很清楚怎么解决它。 无线呢? 也很简单

针对于无线的情况(是WEP网络):
$ sudo ifconfig wlan0 hw ether xxxxxxxx
$ sudo iwlist wlan0 scan
可以得到ssid名~~
$ sudo iwconfig wlan0 ssid 'who' key 'password'
$ sudo route add default gw 10.3.52.1










Monday, June 21, 2010

由setrlimit引发的学习

 
POSIX标准中有这样一个函数: sysconf(3).  自己写了小段代码:

 19 #include <unistd.h>
 20 #include <stdio.h>
 21
 22 int main(int argc, char *argv[]){
 23     int fd_max_number = sysconf(_SC_OPEN_MAX);
 24     printf("%d\n", fd_max_number);
 25
 26 }

使用strace可以知道它其实是调用了getrlimit(2),
什么limit? 全称为 resource limit. 这是kernel分给每个进程独立的一组数据。代表了进程可以使用的最大resource上限。具体有哪些, 可以见getrlimit(2)的manual

kernel也有一堆limit参数, 使用sysctl(2)来修改, kernel的limit应该被称为"limit of limits"。

下面的有关于文件描述符的limit:
 * http://www.karakas-online.de/forum/viewtopic.php?t=9834
 * 其中提到一点很有意义:file descriptor与open file

在了解setrlimit(2)配置file descriptor时, 有一个文件引起了我的高度注意:
/etc/security/limits.conf

疑问:
1. setrlimit是system call, 为什么会使用这样一个配置文件的?
2. limits.conf是pam_limits module的配置文件, 如果用户不加载此module时,kernel的setrlimit又是处理的?

不解的情况下, 在kernel的源代码堆里纠结时, 发现了一个常常会看到的一个词:SELinux
FAQ了一把, 得知SELinux是在kernel里加入复杂的access control。比如role-based access control

疑问又来了: Linux是一个可高度裁剪(scale)的系统, 如何做到去掉Linux Security Modules可以不影响现有的system call的呢?

这其中的机制比较吸引我。 google了一把, 得到一篇好文, 分享:
 * http://www.ibm.com/developerworks/linux/library/l-selinux/





Wednesday, June 9, 2010

系统里的hostname

1. 修改host name需要reboot吗?
2. host name与/etc/hosts有什么关系呢?
3. gethostname为什么不受/etc/nsswitch.conf的配置?

这三个问题在不了解host name是什么的时候, 比较纠结.

是否要reboot这个问题是最直接让我产生dig这个host name的动力, 还有就是工作中, 碰到一台机器无法使用sudo命令, 于是花时间学习学习.

平时看hostname(3)时, 发现hostname(3)与/etc/nsswitch.conf扯在一起, 这使host name与DNS中的记录纠结在一起. 更是希望了解之间的关系

在找资料的过程中, 本人发现了一个很有意思的方法:
 * Linux kernel与GNU分开.
什么意思呢? 分界是为了把不同时期的产物, 概念之类的分开. 比如: 当你认host name是kernel的一个变量时, 那么它就与DNS中的记录有明显的不同.

gethostname是system call, 它不是glibc的东西, 所以它与glibc中的DNS查询机制(/etc/nsswitch.conf)是扯不上关系的. gethostbyname, gethostbyaddr都是glibc的东西

就算没有glibc的存在, kernel中的host name照样存在!

按上面的方法, 已经可以很清楚地知道host name与/etc/hosts, /etc/nsswitch.conf是没有关系的.

linux kernel提供了实时修改kernel参数的方法, 是无需要reboot内核就可以生效的.  如sysctl(2), 也有CLI的sysctl(3). 也可以修改/proc/sys/kernel下的文件.

在实际中, GNU软件又常常会使用到host name!

在工作中碰到一个这样的问题: 每当运行sudo时shell就hang住!
它被block了吗?
于是使用strace一查, sudo是在等socket的IO. 发现这台机器的DNS請求是发不出去的

为什么sudo需要使用网络呢?
这其实就是程序期望得到FQDN格式的host name的結果.
得到FQDN格式的host name就使得host  name与DNS查询纠结在一起.

通过学习hostname命令的代码, 可以得到hostname -f其实是等同于下面的代码
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>

int main(int argc, char *argv[]){
    char hostname[64];
    if ( gethostname( hostname, sizeof(hostname) ) != 0){
        perror("1");
    }   
    struct hostent * host_struct;
    if ( (host_struct = gethostbyname( hostname )) == NULL ){
        perror("2");
    }   
    printf("%s\n", host_struct->h_name);

}

可以得到这样的信息: 得到FQDN格式的host name, 是需要使用到
1. host name
2. DNS
这就与linux下DNS查询顺序策略有关系(/etc/nsswitch.conf)


python里有一段很明了的代码(来自socket.py):
def getfqdn(name=''):
    """Get fully qualified domain name from name.

    An empty argument is interpreted as meaning the local host.

    First the hostname returned by gethostbyaddr() is checked, then
    possibly existing aliases. In case no FQDN is available, hostname
    from gethostname() is returned.
    """
    name = name.strip()
    if not name or name == '0.0.0.0':
        name = gethostname()
    try:
        hostname, aliases, ipaddrs = gethostbyaddr(name)
    except error:
        pass
    else:
        aliases.insert(0, hostname)
        for name in aliases:
            if '.' in name:
                break
        else:
            name = hostname
    return name

这样还可以解开一个疑问: 为什么/etc/hosts里常常会出现hostname和它的FQDN记录
增加这样的信息在这里, 查hostname的FQDN时就无须通过网络得到, 当然, 的确有需求的话, 也是可以的, 如果牛B的话, 就每台机器有一个全球唯一的域名也没有人说