天天看點

Openstack 調用socket RAW 權限問題

在Openstack中實作節點高可用的方案中,探測實體節點當機現象,在程式中調用了socket  RAW 協定,但是必須具備root 使用者權限,而openstack程式調用是nova使用者,于是做了這樣的事情,希望能幫助大家

1, 程式調用的錯誤

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task Traceback (most recent call last):</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task   </code><code>File</code><code>"/usr/lib/python2.6/site-packages/nova/openstack/common/periodic_task.py"</code><code>, line </code><code>180</code><code>, inrun_periodic_tasks</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task     task(</code><code>self</code><code>, context)</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task   </code><code>File</code><code>"/usr/lib/python2.6/site-packages/nova/extend/manager.py"</code><code>, line </code><code>91</code><code>, inhealth_check_host</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task     ifnot  icmp_ping.icmp_ping(node_resource[s][</code><code>'host_ip'</code><code>]) </code><code>and</code><code>\</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task   </code><code>File</code><code>"/usr/lib/python2.6/site-packages/nova/extend/icmp_ping.py"</code><code>, line </code><code>157</code><code>, inicmp_ping</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task     delay  </code><code>=</code>  <code>do_one(dest_addr, CONF.timeout)</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task   </code><code>File</code><code>"/usr/lib/python2.6/site-packages/nova/extend/icmp_ping.py"</code><code>, line </code><code>136</code><code>, indo_one</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task     ping_socket </code><code>=</code><code>socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task   </code><code>File</code><code>"/usr/lib/python2.6/site-packages/eventlet/greenio.py"</code><code>, line </code><code>116</code><code>, in__init__</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task     fd </code><code>=</code><code>_original_socket(family_or_realsock, </code><code>*</code><code>args, </code><code>*</code><code>*</code><code>kwargs)</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task   </code><code>File</code><code>"/usr/lib64/python2.6/socket.py"</code><code>, line </code><code>184</code><code>, in__init__</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task     _sock </code><code>=</code><code>_realsocket(family, </code><code>type</code><code>, proto)</code>

<code>2014</code><code>-</code><code>03</code><code>-</code><code>1309</code><code>:</code><code>33</code><code>:</code><code>08.4081916TRACE</code> <code>nova.openstack.common.periodic_task error: [Errno </code><code>1</code><code>] Operation notpermitted</code>

2,icmp_ping 的實作,這是網上一個哥們寫的ICMP 的實,下次找到貼上去,,我拿過來做了一些修改,希望作者不要見怪

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

<code># vim: tabstop=4 shiftwidth=4 softtabstop=4</code>

<code># Copyright 2010 United States Government as represented by the</code>

<code># Administrator of the National Aeronautics and Space Administration.</code>

<code># All Rights Reserved.</code>

<code># Copyright (c) 2010 Citrix Systems, Inc.</code>

<code># Copyright 2011 Ken Pepple</code>

<code>#</code>

<code>#    Licensed under the Apache License, Version 2.0 (the "License"); you may</code>

<code>#    not use this file except in compliance with the License. You may obtain</code>

<code>#    a copy of the License at</code>

<code>#         http://www.apache.org/licenses/LICENSE-2.0</code>

<code>#    Unless required by applicable law or agreed to in writing, software</code>

<code>#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT</code>

<code>#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the</code>

<code>#    License for the specific language governing permissions and limitations</code>

<code>#    under the License.</code>

<code>""" To detect physical nodes is active, according to the sock. Write the daemon ICMP protocol """</code>

<code>importos</code>

<code>importsys</code>

<code>#import socket</code>

<code>importstruct</code>

<code>importselect</code>

<code>importtime</code>

<code>importtraceback</code>

<code>fromoslo.config importcfg</code>

<code>fromnova.openstack.common importlog as logging</code>

<code>fromeventlet.green importsocket</code>

<code>icmp_opts </code><code>=</code><code>[</code>

<code>    </code><code>cfg.StrOpt(</code><code>'timeout'</code><code>,</code>

<code>               </code><code>default</code><code>=</code><code>3</code><code>,</code>

<code>               </code><code>help</code><code>=</code><code>'Setting socket timeout'</code><code>),</code>

<code>    </code><code>cfg.StrOpt(</code><code>'count'</code><code>,</code>

<code>               </code><code>default</code><code>=</code><code>9</code><code>,</code>

<code>               </code><code>help</code><code>=</code><code>'Setting the IMCP PING'</code><code>),</code>

<code>]</code>

<code>CONF </code><code>=</code><code>cfg.CONF</code>

<code>CONF.register_opts(icmp_opts)</code>

<code>LOG </code><code>=</code><code>logging.getLogger(__name__)</code>

<code># From /usr/include/linux/icmp.h; your milage may vary.</code>

<code>ICMP_ECHO_REQUEST </code><code>=</code><code>8</code><code># Seems to be the same on Solaris.</code>

<code>defchecksum(source_string):</code>

<code>    </code><code>"""</code>

<code>    </code><code>I'm not too confident that this is right but testing seems</code>

<code>    </code><code>to suggest that it gives the same answers as in_cksum in ping.c</code>

<code>    </code><code>sum</code><code>=</code><code>0</code>

<code>    </code><code>countTo </code><code>=</code><code>(</code><code>len</code><code>(source_string)</code><code>/</code><code>2</code><code>)</code><code>*</code><code>2</code>

<code>    </code><code>count </code><code>=</code><code>0</code>

<code>    </code><code>whilecount&lt;countTo:</code>

<code>        </code><code>thisVal </code><code>=</code><code>ord</code><code>(source_string[count </code><code>+</code><code>1</code><code>])</code><code>*</code><code>256</code><code>+</code><code>ord</code><code>(source_string[count])</code>

<code>        </code><code>sum</code><code>=</code><code>sum</code><code>+</code><code>thisVal</code>

<code>        </code><code>sum</code><code>=</code><code>sum</code><code>&amp; </code><code>0xffffffff</code><code># Necessary?</code>

<code>        </code><code>count </code><code>=</code><code>count </code><code>+</code><code>2</code>

<code>    </code><code>ifcountTo&lt;</code><code>len</code><code>(source_string):</code>

<code>        </code><code>sum</code><code>=</code><code>sum</code><code>+</code><code>ord</code><code>(source_string[</code><code>len</code><code>(source_string) </code><code>-</code><code>1</code><code>])</code>

<code>    </code><code>sum</code><code>=</code><code>(</code><code>sum</code><code>&gt;&gt; </code><code>16</code><code>)  </code><code>+</code>  <code>(</code><code>sum</code><code>&amp; </code><code>0xffff</code><code>)</code>

<code>    </code><code>sum</code><code>=</code><code>sum</code><code>+</code><code>(</code><code>sum</code><code>&gt;&gt; </code><code>16</code><code>)</code>

<code>    </code><code>answer </code><code>=</code><code>~</code><code>sum</code>

<code>    </code><code>answer </code><code>=</code><code>answer &amp; </code><code>0xffff</code>

<code>    </code><code># Swap bytes. Bugger me if I know why.</code>

<code>    </code><code>answer </code><code>=</code><code>answer &gt;&gt; </code><code>8</code><code>| (answer &lt;&lt; </code><code>8</code><code>&amp; </code><code>0xff00</code><code>)</code>

<code>    </code><code>returnanswer</code>

<code>defreceive_one_ping(ping_socket, </code><code>ID</code><code>, timeout):</code>

<code>    </code><code>receive the ping from the socket.</code>

<code>    </code><code>timeLeft </code><code>=</code><code>timeout</code>

<code>    </code><code>whileTrue:</code>

<code>        </code><code>startedSelect </code><code>=</code><code>time.clock()</code>

<code>        </code><code>whatReady </code><code>=</code><code>select.select([ping_socket], [], [], timeLeft)</code>

<code>        </code><code>howLongInSelect </code><code>=</code><code>(time.clock() </code><code>-</code><code>startedSelect)</code>

<code>        </code><code>ifwhatReady[</code><code>0</code><code>] </code><code>=</code><code>=</code><code>[]: </code><code># Timeout</code>

<code>            </code><code>return</code>

<code>        </code><code>timeReceived </code><code>=</code><code>time.clock()</code>

<code>        </code><code>recPacket, addr </code><code>=</code><code>ping_socket.recvfrom(</code><code>1024</code><code>)</code>

<code>        </code><code>icmpHeader </code><code>=</code><code>recPacket[</code><code>20</code><code>:</code><code>28</code><code>]</code>

<code>        </code><code>type</code><code>, code, checksum, packetID, sequence </code><code>=</code><code>struct.unpack(</code>

<code>            </code><code>"bbHHh"</code><code>, icmpHeader</code>

<code>        </code><code>)</code>

<code>        </code><code>ifpacketID </code><code>=</code><code>=</code><code>ID</code><code>:</code>

<code>            </code><code>bytesInDouble </code><code>=</code><code>struct.calcsize(</code><code>"d"</code><code>)</code>

<code>            </code><code>timeSent </code><code>=</code><code>struct.unpack(</code><code>"d"</code><code>, recPacket[</code><code>28</code><code>:</code><code>28</code><code>+</code><code>bytesInDouble])[</code><code>0</code><code>]</code>

<code>            </code><code>returntimeReceived </code><code>-</code><code>timeSent</code>

<code>        </code><code>timeLeft </code><code>=</code><code>timeLeft </code><code>-</code><code>howLongInSelect</code>

<code>        </code><code>iftimeLeft &lt;</code><code>=</code><code>0</code><code>:</code>

<code>defsend_one_ping(ping_socket, dest_addr, </code><code>ID</code><code>):</code>

<code>    </code><code>Send one ping to the given &gt;dest_addr&lt;.</code>

<code>    </code><code>dest_addr  </code><code>=</code>  <code>socket.gethostbyname(dest_addr)</code>

<code>    </code><code># Header is type (8), code (8), checksum (16), id (16), sequence (16)</code>

<code>    </code><code>my_checksum </code><code>=</code><code>0</code>

<code>    </code><code># Make a dummy heder with a 0 checksum.</code>

<code>    </code><code>header </code><code>=</code><code>struct.pack(</code><code>"bbHHh"</code><code>, ICMP_ECHO_REQUEST, </code><code>0</code><code>, my_checksum, </code><code>ID</code><code>, </code><code>1</code><code>)</code>

<code>    </code><code>bytesInDouble </code><code>=</code><code>struct.calcsize(</code><code>"d"</code><code>)</code>

<code>    </code><code>data </code><code>=</code><code>(</code><code>192</code><code>-</code><code>bytesInDouble) </code><code>*</code><code>"Q"</code>

<code>    </code><code>data </code><code>=</code><code>struct.pack(</code><code>"d"</code><code>, time.clock()) </code><code>+</code><code>data</code>

<code>    </code><code># Calculate the checksum on the data and the dummy header.</code>

<code>    </code><code>my_checksum </code><code>=</code><code>checksum(header </code><code>+</code><code>data)</code>

<code>    </code><code>header </code><code>=</code><code>struct.pack(</code>

<code>        </code><code>"bbHHh"</code><code>, ICMP_ECHO_REQUEST, </code><code>0</code><code>, socket.htons(my_checksum), </code><code>ID</code><code>, </code><code>1</code>

<code>    </code><code>)</code>

<code>    </code><code>packet </code><code>=</code><code>header </code><code>+</code><code>data</code>

<code>    </code><code>ping_socket.sendto(packet, (dest_addr, </code><code>1</code><code>)) </code><code># Don't know about the 1</code>

<code>defdo_one(dest_addr, timeout):</code>

<code>    </code><code>Returns either the delay (in seconds) or none on timeout.</code>

<code>    </code><code>icmp </code><code>=</code><code>socket.getprotobyname(</code><code>"icmp"</code><code>)</code>

<code>    </code><code>try</code><code>:</code>

<code>        </code><code>ping_socket </code><code>=</code><code>socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)</code>

<code>        </code><code>#ping_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)</code>

<code>    </code><code>exceptsocket.error, (errno, msg):</code>

<code>        </code><code>iferrno </code><code>=</code><code>=</code><code>1</code><code>:</code>

<code>            </code><code># Operation not permitted</code>

<code>            </code><code>msg </code><code>=</code><code>msg </code><code>+</code><code>(</code>

<code>                </code><code>" - Note that ICMP messages can only be sent from processes"</code>

<code>                </code><code>" running as root."</code>

<code>            </code><code>)</code>

<code>            </code><code>LOG.error(socket.error(msg))</code>

<code>        </code><code>raise</code><code># raise the original error</code>

<code>    </code><code>my_ID </code><code>=</code><code>os.getpid() &amp; </code><code>0xFFFF</code>

<code>    </code><code>send_one_ping(ping_socket, dest_addr, my_ID)</code>

<code>    </code><code>delay </code><code>=</code><code>receive_one_ping(ping_socket, my_ID, timeout)</code>

<code>    </code><code>ping_socket.close()</code>

<code>    </code><code>returndelay</code>

<code>deficmp_ping(dest_addr):</code>

<code>    </code><code>active </code><code>=</code><code>False</code>

<code>    </code><code>fori inxrange(CONF.count):</code>

<code>        </code><code>try</code><code>:</code>

<code>            </code><code>delay  </code><code>=</code>  <code>do_one(dest_addr, CONF.timeout)</code>

<code>        </code><code>exceptsocket.gaierror, e:</code>

<code>            </code><code>active </code><code>=</code><code>False</code>

<code>            </code><code>break</code>

<code>        </code><code>ifdelay  </code><code>=</code><code>=</code>  <code>None</code><code>:</code>

<code>        </code><code>else</code><code>:</code>

<code>            </code><code>active </code><code>=</code><code>True</code>

<code>    </code><code>return</code>  <code>active</code>

3,我單獨寫了一個openstack 的元件,來實作高可用(nova-extend),用他來調用 ICMP_PING

<code>"""Starter script for Nova Extend."""</code>

<code>fromnova importconfig</code>

<code>fromnova importobjects</code>

<code>fromnova importservice</code>

<code>fromnova importutils</code>

<code>CONF.import_opt(</code><code>'topic'</code><code>, </code><code>'nova.extend.api'</code><code>, group</code><code>=</code><code>'extend'</code><code>)</code>

<code>defmain():</code>

<code>    </code><code>objects.register_all()</code>

<code>    </code><code>config.parse_args(sys.argv)</code>

<code>    </code><code>logging.setup(</code><code>"nova"</code><code>)</code>

<code>    </code><code>utils.monkey_patch()</code>

4, nova-extend 啟動服務的時候會調用nova.extend.manager.ExtendManager

<code>ifnot  icmp_ping.icmp_ping(node_resource[s][</code><code>'host_ip'</code><code>]) </code><code>and</code><code>\</code>

<code>                            </code><code>utils.is_false(CONF.extend_high_availability):</code>

<code>            </code><code>LOG.info(</code><code>"The compute node [%s] is down "</code><code>%</code><code>s)</code>

<code>            </code><code>instances_uuid </code><code>=</code><code>db.instances_uuid_by_host(context,s)</code>

5, 程式就會報錯,

<code>2</code>

6 ,我用python 調用是OK 的,但是openstack調用依然報錯,我以為是協程限制導緻,豈不是,我是這樣處理的

   1, copy /usr/bin/python /usr/bin/python-extend

   2,  chown root:root /usr/bin/python-extend

   3, chmod ug+s /usr/bin/python-extend

   4,  修改/usr/bin/nova-extend

      #!/usr/bin/python-extend

   5,重新開機服務就OK 了

本文轉自 swq499809608 51CTO部落格,原文連結:http://blog.51cto.com/swq499809608/1375260

上一篇: samba服務
下一篇: scp

繼續閱讀