Lei Chen

Solaris/OpenSolaris上使用3G -- Using 3G modems on Solaris

Monday Nov 16, 2009

跟华为EC1260 modem斗争了几天,终于能勉强上中国电信的3G网络了。从google出来的网上信息中,可以看到这个modem在插入主机后,需要主机发送几个USB命令将它的运行模式从存储设备转换到modem模式。通过某些方法,可以看到在windows上这个modem的driver都发送了哪些命令,也可以参考Linux上的专门针对这一系列2G/3G USB modem的软件:usb_modeswitch。这个软件与我的想法不谋而合 ---- 用libusb发送控制命令。

Having struggled with Huawei EC1260 USB modem for several days, finally and fortunately I make it work on Solaris. This device looks as a storage device. It has its own driver and dial-up applications in this storage device. When it is plugged into a Windows host for the first time, it will be self-extracted and ask for user's intervention to install the driver and application. Afterwards, whenever user plugs the modem into this Windows host, the driver will do some switch work for it.

I don't have too much knowledge of how Linux handles it. But it seems Linux kernel drivers(storage) do send some commands upon detecting a Huawei USB modem. From my experiments on Solaris, I don't think merely sending a SET_FEATURE request can switch this device. So, there's also a Linux specific application, usb_modeswitch. I happen to have the same idea with it, i.e. using libusb(3lib) to send control messages. It's much more flexible.


我写了一个简单的libusb(3lib)程序用于切换Huawei EC1260设备,如果你的设备也能用这个程序进行切换,请留言。下载、编译、并运行此程序(请仔细阅读程序注释中的信息):SwitchModem

 I wrote a simple libusb application to switch EC1260. If you have a Huawei device, you can download it and have a try. But, please change the product ID to your device's before compiling it. Click on the above SwitchModem link to download the application. Compile and run it. It will switch Huawei modem from storage to modem mode. If it works for your device or you have questions, please leave a message or post to wwan-discuss AT opensolaris.org.


解决了最关键的设备问题,剩下的就是在Solaris上的配置了。

首先,为这个modem绑定一个driver。由于这个Modem不是USB CDC-ACM 标准设备(但是仍然可以使用usbsacm(7D) driver),我们必须手动添加此设备的alias,即:

On Solaris, we use usbsacm(7D) to drive USB CDC-ACM compliant and similar devices. You need to bind this driver to the Huawei USB modems. After switching, the product ID of EC1260 is changed from 0x1446 to 0x1001. The procedure is as the following:

#update_drv -a -i 'usb12d1,1001' usbsacm

注意:EC1260在完成switch后,不是原来的PID 0x1446了,而是使用了0x1001。

第二步,设置ppp拨号脚本。Set up dial-up configurations:

# cat /etc/ppp/peers/huawei
term/0
460800
connect "/usr/bin/chat -V -t60 -f /etc/ppp/huawei-chat"
asyncmap 00000000
crtscts
defaultroute
holdoff 1
lcp-echo-interval 0
noauth
noccp
novj
passive
updetach
usepeerdns
name CARD
password CARD

# cat /etc/ppp/huawei-chat
ABORT BUSY
ABORT 'NO CARRIER'
ABORT ERROR
REPORT CONNECT
'' 'AT+CPIN?'
TIMEOUT 5
READY-AT+CPIN=????-OK 'AT&F'
OK ATE
OK 'ATZ Q0 V1 E1 S0=0 &C1 &D2 +FCLASS=0'
SAY '\nCalling ChinaTelcom'
OK 'ATDT#777'
TIMEOUT 60
CONNECT \n

辅助脚本:

$ cat /etc/ppp/ip-up
#!/usr/bin/ksh
cp /etc/ppp/resolv.conf /etc
cp /etc/nsswitch.dns /etc/nsswitch.conf


$ cat /etc/ppp/ip-down
#!/usr/bin/ksh
cp /etc/nsswitch.nis /etc/nsswitch.conf

一切配置完成,那就开始拨号吧:

$ pppd call huawei
AT+CPIN?
+CPIN:READY

OK
AT&F
OK
Calling ChinaTelcom
AATZ Q0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
OK
ATDT#777
CONNECTchat:  Nov 16 13:58:09 CONNECT
Serial connection established.
Using interface sppp0
Connect: sppp0 <--> /dev/term/4
Remote message: ^@
local  IP address 124.127.63.2
remote IP address 115.168.64.86
primary   DNS address 219.141.136.10
secondary DNS address 219.141.140.10

如果你在使用USB 3G modem过程中遇到问题,可以给我留言,如果能够提供设备信息,我们就可以更快地解决问题。得到硬件信息,请运行mdb命令:

If you have trouble with your USB 3G modems, please use the following command to get the hardware information and post it to  wwan-discuss AT opensolaris.org  for help.

[root@~]$ mdb -k
Loading modules: [ unix genunix specfs dtrace mac cpu.generic uppc pcplusmp rootnex scsi_vhci ufs sockfs ip hook neti sctp arp usba uhci stmf fctl nca lofs zfs idm cpc random nfs fcip logindmux ptm sppp sd ]
> ::prtusb

INDEX   DRIVER      INST  NODE            VID.PID     PRODUCT             
1       ehci        0     pci1028,151     0000.0000   No Product String
2       hubd        5     hub             050d.0234   No Product String
3       ehci        1     pci1735,e0      0000.0000   No Product String
4       uhci        0     pci1028,151     0000.0000   No Product String
5       uhci        1     pci1028,151     0000.0000   No Product String
6       uhci        2     pci1028,151     0000.0000   No Product String
7       uhci        3     pci1028,151     0000.0000   No Product String
8       ohci        0     pci1735,35      0000.0000   No Product String
9       hubd        0     hub             0451.2046   No Product String
a       ohci        1     pci1735,35      0000.0000   No Product String
b       hubd        1     hub             0451.2046   No Product String
c       usb_mid     0     device          050d.0105   Belkin OmniView KVM Switch
d       hid         2     mouse           413c.3010   No Product String
e       usbsacm     4     device          12d1.1001   HUAWEI Mobile
>  ::prtusb -i e -v
INDEX   DRIVER      INST  NODE            VID.PID     PRODUCT            
e       usbsacm     4     device          12d1.1001   HUAWEI Mobile

Device Descriptor
{
    bLength = 0x12
    bDescriptorType = 0x1
    bcdUSB = 0x110
    bDeviceClass = 0
    bDeviceSubClass = 0
    bDeviceProtocol = 0
    bMaxPacketSize0 = 0x40
    idVendor = 0x12d1
    idProduct = 0x1001
    bcdDevice = 0
    iManufacturer = 0x1
    iProduct = 0x2
    iSerialNumber = 0x4
    bNumConfigurations = 0x1
}
    -- Active Config Index 0
    Configuration Descriptor
    {
        bLength = 0x9
        bDescriptorType = 0x2
        wTotalLength = 0x6c
        bNumInterfaces = 0x4
        bConfigurationValue = 0x1
        iConfiguration = 0x0
        bmAttributes = 0xa0
        bMaxPower = 0xfa
    }
        Interface Descriptor
>> More [<space>, <cr>, q, n, c, a] ?

[0] Comments
Like this post? del.icio.us | furl | slashdot | technorati | digg

Solaris Security

Thursday Jun 12, 2008

Solairs系统安全

Solaris是一个复杂的系统,为了满足各种安全要求,Solaris变得更加复杂。虽然我既不是一个系统管理员,也不是安全管理员。但是,在做项目时,不得不面对Solaris系统安全的要求。进入Solaris核心的各种软件,不管是driver,还是应用程序,都必须符合Solaris安全规范。前一段时间,为了过一个PSARC,特意恶补了一下这些方面的知识。就像一个同事在他的blog中说的那样,这些东西自己看,或者别人给你讲,你能在24小时之内记住和理解。过了这个时间,又会混沌起来。所以还是记下来的好。

Security涉及的东西太多,我只能总结自己所看的那些部分:

1. RBAC

2. Privileges

3. Device management

4. Audit

5. Cryptography

至于authentication方面的内容,还是看Solaris文档吧,对于Trusted ExtensionTX)本人更是缺乏了解,等下次有机会做相关项目的时候再写吧。

1. RBAC

RBACrole-based access control)是Solaris中用户权限管理的基础架构。对于进程,在kernel中又增加了额外的privilege限制。PrivilegeRBAC配合就可以提供一个更安全可靠的系统环境.

RBAC包含的要素:

首先是authorization,所谓授权是指在用户空间(相对于内核空间而言)中给予一个用户或者角色的一个权限,允许他执行某个动作。系统上所有的授权都定义在文件/etc/security/auth_attr中。应用程序如果需要检查其执行者的授权,需要在程序中调用chkauthattr3SECDB)来检查。

例如,我们新设计了一个程序,定义了一个授权,称为solaris.device.wusb.add。我们将这个定义加入到/etc/security/auth_attr文件中。在WUSB的应用程序中,就要调用chkauthattr(“solaris.device.wusb.add”,userid)来检查用户授权。如果我们允许用户使用WUSB设备,就要把这个授权给予用户或角色(通过usermod(1M)或者rolemod1M))。实际上这一授权被加到文件/etc/user_attr中。

强调一下,所有对于authorization的操作和检查都是在用户空间做的。

Privilege,授予一个命令、用户、角色或系统的一个权利。在进程执行时,由内核来检查这种权利。Privilege是由系统定义好了的,参见privileges(5)。根据你的项目的需要,需要选择合适的privilege。可以使用命令ppriv(1)来查看一个程序所需要的privileges。这样就可以把这个程序恰好所需的privilege授予此程序或用户,不会给他过度的权利,也不会因为缺少某个privilege而无法运行此程序。

Security attribute:让进程能够执行某个操作的一个属性。在Unix环境中,一个security attribute能够让进程执行普通用户不能执行的操作。比如,setuidsetgid程序就具备security attribute。在RBAC模型中,authorizationprivilege也是security attributes

Privileged application:具备security属性的程序或命令。可以是检查uidgid的程序;可以是检查privilege的程序(这种程序又称为privilege-aware程序);也可以是检查authorization的程序。

Rights profile:一个集合,一个能够分配给角色或者用户的一组能力的集合。一个rights profile可以是一些授权,具有安全属性的命令,或者是其它rights profile的组合。参见文件/etc/security/prof_attr, /etc/security/exec_attr

Role:一种用于执行特权操作的特殊ID。这种ID不能用于系统登陆,用户必须首先以自己的帐号登陆,之后使用su(1M)把自己assume成某个角色。系统管理员需要将某个角色分配给用户,用户才能su成那个角色。一旦成为了那个角色,他就具备了授予此角色的所有特权和能力。

关于userrolerights profileauthorizationprivilege可以用一个图来表示:
RBAC relations
在上图中出现了几个重要文件,称为RBAC数据库文件:

user_attr:包含了userrole的信息,是/etc/passwd/etc/shadow文件的重要补充。RBAC依赖于此文件来查看userrole的额外权限。此文件中的每一表项表示了一个帐号的属性,如具有哪些authsprofile,或role

虽然sysadmin可以将authprivilegeprofile直接授予user,但是RBAC并不推荐这样做。首先,如果将某个privilege给予了用户,那么他将一直具有这项特权,即使在运行某些不需要这些特权的程序。例如,如果FILE_DAC_WRITE给予了一个普通用户,那就意味着他可以写不属于他的文件,文件权限在此不起作用。这是很危险的做法。其次,rights profile直接授予用户可能无法达到预期效果。在此就要提一下profile shell,它是一种特殊的shell,能够识别程序的security attributes。在普通的shell中,即使你把某个privilege给予了某个命令,并包含在某个profile中,用户具有此profile也无法获得那个程序所需的privilege。必须使用pfsh, pfcsh, pfksh。当然,对于role,在执行su 时,自动运行profile shell

auth_attr:定义了一系列的授权。每一表项对应一个authorization定义,包含了authnamedescription,及属性。

prof_attr:定义了一系列的rights profile。每一个表项对应一个rights profile,包含了namedescription,及所具备的authorizations。需要注意的是,与一个rights profile对应的特权命令的定义并不在此,而是在exec_attr中。

exec_attr:此文件中的每一个表项都定义了一个命令所需的权限。每一个表项包含一个prof_name, policy(suser/solaris), type(cmd), id(the cmd’s full path), attr(euid, uid, egid, gid; privs)。需要注意,这里的prof_name必须是prof_attr中定义的,否则你定义的这一表项就没有任何意义。当一个帐号得到了一个rights profile时,它也具备了exec_attr中对应的命令的执行能力和权限。

2. Privileges

在前面已经提到了privilegePrivilege是进程执行某种操作时所需要的权利,由内核强加的一种限制。传统的系统的superuser模式中,进程要么以root运行,要么以普通用户身份运行。受file permission的限制,普通用户只能读写自己的文件。如果需要额外的权限,就要使用setuid的方法以root运行,并因此获得root的所有权限,就像passwd(1)。实际上,也许这个程序不需要root的所有权限。

Privilege模式的好处在上面已经提到,就是一个程序真的需要某种额外权限时,可以通过profile给它。用户有了这个profile就可以执行它,完成后,就不再具有这种权限。进程在此过程中,只能得到所需的权限,而无法获得更多的权限,也就无法滥用权限。这种方式又称为least privilege原则。

在我们的项目中,需要处理一个特殊的privilege。你平时也许没有注意到,ioctl(2)可能存在着漏洞。很多device node都是644权限,这就是说普通用户能够以O_RDONLY打开这些节点。只能你能打开它,你就可以发送ioctl命令给driver,而很多driver并没有检查用户权限,这样就意味着普通用户可以操作一个设备,比如停掉这个设备。这显然是一个问题。解决这个问题的办法就是在driver中检查用户的privilege,用drv_priv(9F)。它是要检查调用程序是否具有PRIV_SYS_DEVICES权限。

每一个进程都具有四组privilege,即effective privileges, Permitted privileges, Inheritable privilegeslimit privileges.具体每种privilege集合的含义,请参见相关文档。

进程可以通过继承得到privilege,也可以通过profile被分配某种privilege

Privilegedebug方法是使用ppriv(1)truss(1)相互配合,以便决定合适的privilege

3. Device management

Privilege同样可以用于保护设备,也就是所谓的device policyadd_drv(1M)update_drv(1M)命令可以设定某个节点或driverprivilege

另外一个概念就是device allocation。在Solaris系统中,设备都是可以被分配的。一旦设备被分配给了某个用户(调用命令allocate(1)),他就会一直占有这个设备,直到显式地释放(调用命令deallocate(1)),被特权用户抢占,或者用户退出登录,设备才能被其它用户使用。需要注意的是,属于一个用户的object在整个过程中都不应该暴露于其它用户。例如,如果使用audio进行了录音或配置了audio的某些参数,在他deallocate这个audio设备后,系统不应该遗留任何的录音数据或配置信息。这就是所谓的object reuse问题。如果driver不能做到这一点,就需要在device allocation子系统中加入清理脚本(device-clean)。用户allocate设备是需要一定的授权的,即solaris.device.allocate授权。

如果需要device allocation功能,sysadmin必须运行bsmconv(1M)Solaris缺省的可分配的设备包括 audiotapediskette driveCD-ROM设备。如果需要分配其它设备,则必须自己手动加入。这里面涉及到几个文件,/etc/security/device_allocate, /etc/security/device_maps, /etc/security/dev/

device_maps:包含了许多表项,每个表项都是由device-name, device-type, device-list组成。例如:

fd0:\

fd:\

/dev/diskette /dev/rdiskette /dev/fd0a /dev/rfd0a \

/dev/fd0b /dev/rfd0b /dev/fd0c /dev/fd0 /dev/rfd0c /dev/rfd0:\

device_allocate:可分配设备的列表。每一个表项包含了device-namedevice-type, authsdevice-exec(cleanup script)。例如:

sr0;sr;reserved;reserved;solaris.device.allocate;/etc/security/lib/sr_clean

任何设备如果希望被分配,都必须首先被加入到这两个文件中。之后,用户才能调用allocate(1)分配这个设备。

虽然device allocation在以后也许会被取代,但在做项目的过程中还是需要考虑,因为有PSARCsecurity专家会challenge你。关于这一点可以参见PSARC2008/170以及LSARC 2007/018

4. Audit

Solaris audit能够对系统的许多行为进行审计,比如系统的启动/关闭,用户登录/退出,进程和线程的创建/退出,RBACrole的变换、authprivilege的获取情况,甚至包括系统调用,如open(2), close(2)等。Audit的使用比较直观,一般来说,新的项目利用现有的audit功能就能够满足Solarisaudit要求了。在我们的项目中,就是依赖现有的Solaris auditRBAC的审计能力。我们没有对这个项目中具体的一个添加表项动作进行audit,如果需要这样做,那就只能参考其它现有项目的源代码了,因为我没有看到audit的公开编程接口。

5. Cryptography

 Solaris系统在用户层和内核中提供了许多加解密算法的接口。关于这方面的内容可以参考“Solaris Security for Developers Guide”。当然这本手册中的大部分内容都是关于用户层的。如果需要在driver中使用加密算法,就只能参考其它项目或者ARC文档了。在用户层,可以查阅libpkcs11(3lib),libkmf(3LIB)。在kernel中,需要查看头文件sys/crypto/common.h和sys/crypto/api.h。

[2] Comments
Like this post? del.icio.us | furl | slashdot | technorati | digg