Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
ebb30424
Commit
ebb30424
authored
8 years ago
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use process except thread
parent
216163f4
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
224 additions
and
79 deletions
+224
-79
ssh_config.py
terminal/ssh_config.py
+105
-0
ssh_config_example.py
terminal/ssh_config_example.py
+29
-26
ssh_server.py
terminal/ssh_server.py
+81
-53
utils.py
terminal/utils.py
+9
-0
web_ssh_server.py
terminal/web_ssh_server.py
+0
-0
No files found.
terminal/ssh_config.py
0 → 100644
View file @
ebb30424
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import
logging
import
os
BASE_DIR
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__name__
))
class
Config
:
SSH_HOST
=
''
SSH_PORT
=
2200
LOG_LEVEL
=
'INFO'
LOG_DIR
=
os
.
path
.
join
(
BASE_DIR
,
'logs'
)
LOG_FILENAME
=
'ssh_server.log'
LOGGING
=
{
'version'
:
1
,
'disable_existing_loggers'
:
False
,
'formatters'
:
{
'verbose'
:
{
'format'
:
'
%(levelname)
s
%(asctime)
s
%(module)
s
%(process)
d
%(thread)
d
%(message)
s'
},
'main'
:
{
'datefmt'
:
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
,
'format'
:
'
%(asctime)
s [
%(module)
s
%(levelname)
s]
%(message)
s'
,
},
'simple'
:
{
'format'
:
'
%(levelname)
s
%(message)
s'
},
},
'handlers'
:
{
'null'
:
{
'level'
:
'DEBUG'
,
'class'
:
'logging.NullHandler'
,
},
'console'
:
{
'level'
:
'DEBUG'
,
'class'
:
'logging.StreamHandler'
,
'formatter'
:
'main'
,
'stream'
:
'ext://sys.stdout'
,
},
'file'
:
{
'level'
:
'DEBUG'
,
'class'
:
'logging.FileHandler'
,
'formatter'
:
'main'
,
'mode'
:
'a'
,
'filename'
:
os
.
path
.
join
(
LOG_DIR
,
LOG_FILENAME
),
},
},
'loggers'
:
{
'jumpserver'
:
{
'handlers'
:
[
'console'
,
'file'
],
# 'level': LOG_LEVEL_CHOICES.get(LOG_LEVEL, None) or LOG_LEVEL_CHOICES.get('info')
'level'
:
LOG_LEVEL
,
'propagate'
:
True
,
},
'jumpserver.web_ssh_server'
:
{
'handlers'
:
[
'console'
,
'file'
],
# 'level': LOG_LEVEL_CHOICES.get(LOG_LEVEL, None) or LOG_LEVEL_CHOICES.get('info')
'level'
:
LOG_LEVEL
,
'propagate'
:
True
,
},
'jumpserver.ssh_server'
:
{
'handlers'
:
[
'console'
,
'file'
],
# 'level': LOG_LEVEL_CHOICES.get(LOG_LEVEL, None) or LOG_LEVEL_CHOICES.get('info')
'level'
:
LOG_LEVEL
,
'propagate'
:
True
,
}
}
}
def
__init__
(
self
):
pass
def
__getattr__
(
self
,
item
):
return
None
class
DevelopmentConfig
(
Config
):
pass
class
ProductionConfig
(
Config
):
pass
class
TestingConfig
(
Config
):
pass
config
=
{
'development'
:
DevelopmentConfig
,
'production'
:
ProductionConfig
,
'testing'
:
TestingConfig
,
'default'
:
DevelopmentConfig
,
}
env
=
'default'
if
__name__
==
'__main__'
:
pass
This diff is collapsed.
Click to expand it.
terminal/config_example.py
→
terminal/
ssh_
config_example.py
View file @
ebb30424
...
...
@@ -7,20 +7,14 @@ import os
BASE_DIR
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__name__
))
LOG_LEVEL_CHOICES
=
{
'debug'
:
logging
.
DEBUG
,
'info'
:
logging
.
INFO
,
'warning'
:
logging
.
WARNING
,
'error'
:
logging
.
ERROR
,
'critical'
:
logging
.
CRITICAL
}
class
Config
:
LOG_LEVEL
=
''
LOG_LEVEL
=
'
INFO
'
LOG_DIR
=
os
.
path
.
join
(
BASE_DIR
,
'logs'
)
LOGGING
=
{
'version'
:
1
,
'disable_existing_loggers'
:
False
,
'formatters'
:
{
'verbose'
:
{
'format'
:
'
%(levelname)
s
%(asctime)
s
%(module)
s
%(process)
d
%(thread)
d
%(message)
s'
...
...
@@ -47,35 +41,23 @@ class Config:
'level'
:
'DEBUG'
,
'class'
:
'logging.FileHandler'
,
'formatter'
:
'main'
,
'filename'
:
os
.
path
.
join
(
PROJECT_DIR
,
'logs'
,
'jumpserver.log'
)
'filename'
:
LOG_DIR
,
},
},
'loggers'
:
{
'django'
:
{
'handlers'
:
[
'null'
],
'propagate'
:
False
,
'level'
:
LOG_LEVEL
,
},
'django.request'
:
{
'handlers'
:
[
'console'
,
'file'
],
'level'
:
LOG_LEVEL
,
'propagate'
:
False
,
},
'django.server'
:
{
'handlers'
:
[
'console'
,
'file'
],
'level'
:
LOG_LEVEL
,
'propagate'
:
False
,
},
'jumpserver'
:
{
'handlers'
:
[
'console'
,
'file'
],
# 'level': LOG_LEVEL_CHOICES.get(LOG_LEVEL, None) or LOG_LEVEL_CHOICES.get('info')
'level'
:
LOG_LEVEL
,
},
'jumpserver.
users.api
'
:
{
'jumpserver.
web_ssh_server
'
:
{
'handlers'
:
[
'console'
,
'file'
],
# 'level': LOG_LEVEL_CHOICES.get(LOG_LEVEL, None) or LOG_LEVEL_CHOICES.get('info')
'level'
:
LOG_LEVEL
,
},
'jumpserver.
users.view
'
:
{
'jumpserver.
ssh_server
'
:
{
'handlers'
:
[
'console'
,
'file'
],
# 'level': LOG_LEVEL_CHOICES.get(LOG_LEVEL, None) or LOG_LEVEL_CHOICES.get('info')
'level'
:
LOG_LEVEL
,
}
}
...
...
@@ -88,6 +70,27 @@ class Config:
return
None
class
DevelopmentConfig
(
Config
):
pass
class
ProductionConfig
(
Config
):
pass
class
TestingConfig
(
Config
):
pass
config
=
{
'development'
:
DevelopmentConfig
,
'production'
:
ProductionConfig
,
'testing'
:
TestingConfig
,
'default'
:
DevelopmentConfig
,
}
env
=
'default'
if
__name__
==
'__main__'
:
pass
This diff is collapsed.
Click to expand it.
terminal/ssh_server.py
View file @
ebb30424
...
...
@@ -7,6 +7,7 @@ import base64
from
binascii
import
hexlify
import
sys
import
threading
from
multiprocessing
import
process
import
traceback
import
tty
import
termios
...
...
@@ -31,17 +32,21 @@ except IndexError:
pass
from
django.conf
import
settings
from
common.utils
import
get_logger
from
users.utils
import
ssh_key_gen
,
check_user_is_valid
from
utils
import
get_logger
logger
=
get_logger
(
__name__
)
class
SSHServerInterface
(
paramiko
.
ServerInterface
):
host_key_path
=
os
.
path
.
join
(
BASE_DIR
,
'host_rsa_key'
)
channel_pools
=
[]
def
__init__
(
self
):
def
__init__
(
self
,
client
,
addr
):
self
.
event
=
threading
.
Event
()
self
.
client
=
client
self
.
addr
=
addr
self
.
user
=
None
@classmethod
...
...
@@ -70,19 +75,35 @@ class SSHServerInterface(paramiko.ServerInterface):
def
check_auth_password
(
self
,
username
,
password
):
self
.
user
=
check_user_is_valid
(
username
=
username
,
password
=
password
)
if
self
.
user
:
logger
.
info
(
'User:
%
s password auth passed'
%
username
)
logger
.
info
(
'Accepted password for
%(user)
s from
%(host)
s port
%(port)
s '
%
{
'user'
:
username
,
'host'
:
self
.
addr
[
0
],
'port'
:
self
.
addr
[
1
],
})
return
paramiko
.
AUTH_SUCCESSFUL
else
:
logger
.
warning
(
'User:
%
s password auth failed'
%
username
)
logger
.
info
(
'Authentication password failed for
%(user)
s from
%(host)
s port
%(port)
s '
%
{
'user'
:
username
,
'host'
:
self
.
addr
[
0
],
'port'
:
self
.
addr
[
1
],
})
return
paramiko
.
AUTH_FAILED
def
check_auth_publickey
(
self
,
username
,
public_key
):
self
.
user
=
check_user_is_valid
(
username
=
username
,
public_key
=
public_key
)
if
self
.
user
:
logger
.
info
(
'User:
%
s public key auth passed'
%
username
)
logger
.
info
(
'Accepted public key for
%(user)
s from
%(host)
s port
%(port)
s '
%
{
'user'
:
username
,
'host'
:
self
.
addr
[
0
],
'port'
:
self
.
addr
[
1
],
})
return
paramiko
.
AUTH_SUCCESSFUL
else
:
logger
.
warning
(
'User:
%
s public key auth failed'
%
username
)
logger
.
info
(
'Authentication public key failed for
%(user)
s from
%(host)
s port
%(port)
s '
%
{
'user'
:
username
,
'host'
:
self
.
addr
[
0
],
'port'
:
self
.
addr
[
1
],
})
return
paramiko
.
AUTH_FAILED
def
get_allowed_auths
(
self
,
username
):
...
...
@@ -95,12 +116,20 @@ class SSHServerInterface(paramiko.ServerInterface):
def
check_channel_shell_request
(
self
,
channel
):
self
.
event
.
set
()
self
.
__class__
.
channel_pools
.
append
(
channel
)
return
True
def
check_channel_pty_request
(
self
,
channel
,
term
,
width
,
height
,
pixelwidth
,
pixelheight
,
modes
):
return
True
def
check_channel_window_change_request
(
self
,
channel
,
width
,
height
,
pixelwidth
,
pixelheight
):
logger
.
info
(
'Change window size
%
s *
%
s'
%
(
width
,
height
))
logger
.
info
(
'Change length
%
s '
%
len
(
self
.
__class__
.
channel_pools
))
# for channel in self.__class__.channel_pools:
# channel.send("Hello world")
return
True
class
SSHServer
:
def
__init__
(
self
,
host
=
'127.0.0.1'
,
port
=
2200
):
...
...
@@ -110,18 +139,22 @@ class SSHServer:
self
.
sock
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
self
.
sock
.
bind
((
self
.
host
,
self
.
port
))
self
.
server_ssh
=
None
self
.
server_chan
=
None
self
.
server_channel
=
None
self
.
client_channel
=
None
def
connect
(
self
):
ssh
=
paramiko
.
SSHClient
()
ssh
.
set_missing_host_key_policy
(
paramiko
.
AutoAddPolicy
())
ssh
.
connect
(
hostname
=
'127.0.0.1'
,
port
=
22
,
username
=
'root'
,
password
=
'redhat'
)
self
.
server_ssh
=
ssh
self
.
server_chan
=
channel
=
ssh
.
invoke_shell
(
term
=
'xterm'
)
self
.
server_chan
nel
=
channel
=
ssh
.
invoke_shell
(
term
=
'xterm'
)
return
channel
def
handle_ssh_request
(
self
,
client
,
addr
):
logger
.
info
(
"Get connection from "
+
str
(
addr
))
logger
.
info
(
"Get connection from
%(host)
s:
%(port)
s"
%
{
'host'
:
addr
[
0
],
'port'
:
addr
[
1
],
})
try
:
transport
=
paramiko
.
Transport
(
client
,
gss_kex
=
False
)
transport
.
set_gss_host
(
socket
.
getfqdn
(
""
))
...
...
@@ -132,70 +165,63 @@ class SSHServer:
raise
transport
.
add_server_key
(
SSHServerInterface
.
get_host_key
())
ssh_interface
=
SSHServerInterface
()
ssh_interface
=
SSHServerInterface
(
client
,
addr
)
try
:
transport
.
start_server
(
server
=
ssh_interface
)
except
paramiko
.
SSHException
:
print
(
'*** SSH negotiation failed.'
)
return
channel
=
transport
.
accept
(
20
)
if
channel
is
None
:
self
.
client_channel
=
client_
channel
=
transport
.
accept
(
20
)
if
c
lient_c
hannel
is
None
:
print
(
'*** No channel.'
)
return
print
(
'Authenticated!'
)
channel
.
settimeout
(
100
)
c
lient_c
hannel
.
settimeout
(
100
)
channel
.
send
(
'
\r\n\r\n
Welcome to my dorky little BBS!
\r\n\r\n
'
)
channel
.
send
(
'We are on fire all the time! Hooray! Candy corn for everyone!
\r\n
'
)
channel
.
send
(
'Happy birthday to Robot Dave!
\r\n\r\n
'
)
c
lient_c
hannel
.
send
(
'
\r\n\r\n
Welcome to my dorky little BBS!
\r\n\r\n
'
)
c
lient_c
hannel
.
send
(
'We are on fire all the time! Hooray! Candy corn for everyone!
\r\n
'
)
c
lient_c
hannel
.
send
(
'Happy birthday to Robot Dave!
\r\n\r\n
'
)
server_channel
=
self
.
connect
()
if
not
ssh_interface
.
event
.
is_set
():
print
(
'*** Client never asked for a shell.'
)
return
server_data
=
[]
input_mode
=
True
while
True
:
r
,
w
,
e
=
select
.
select
([
server_channel
,
channel
],
[],
[])
r
,
w
,
x
=
select
.
select
([
client_channel
,
server_
channel
],
[],
[])
if
channel
in
r
:
recv_data
=
channel
.
recv
(
1024
)
.
decode
(
'utf8'
)
# print("From client: " + repr(recv_data)
)
if
len
(
recv_data
)
==
0
:
if
c
lient_c
hannel
in
r
:
data_client
=
client_channel
.
recv
(
1024
)
logger
.
info
(
data_client
)
if
len
(
data_client
)
==
0
:
break
server_channel
.
send
(
recv_data
)
# client_channel.send(data_client)
server_channel
.
send
(
data_client
)
if
server_channel
in
r
:
recv_data
=
server_channel
.
recv
(
1024
)
.
decode
(
'utf8'
)
# print("From server: " + repr(recv_data))
if
len
(
recv_data
)
==
0
:
data_server
=
server_channel
.
recv
(
1024
)
if
len
(
data_server
)
==
0
:
break
channel
.
send
(
recv_data
)
if
len
(
recv_data
)
>
20
:
server_data
.
append
(
'...'
)
else
:
server_data
.
append
(
recv_data
)
try
:
if
repr
(
server_data
[
-
2
])
==
u'
\r\n
'
:
result
=
server_data
.
pop
()
server_data
.
pop
()
command
=
''
.
join
(
server_data
)
server_data
=
[]
print
(
">>> Command:
%
s"
%
command
)
print
(
result
)
except
IndexError
:
pass
print
(
server_data
)
except
Exception
as
e
:
print
(
'*** Caught exception: '
+
str
(
e
.
__class__
)
+
': '
+
str
(
e
))
traceback
.
print_exc
()
try
:
transport
.
close
()
except
:
pass
sys
.
exit
(
1
)
client_channel
.
send
(
data_server
)
# if len(recv_data) > 20:
# server_data.append('...')
# else:
# server_data.append(recv_data)
# try:
# if repr(server_data[-2]) == u'\r\n':
# result = server_data.pop()
# server_data.pop()
# command = ''.join(server_data)
# server_data = []
# except IndexError:
# pass
except
Exception
:
client_channel
.
close
()
server_channel
.
close
()
logger
.
info
(
'Close with server
%
s from
%
s'
%
(
'127.0.0.1'
,
'127.0.0.1'
))
def
listen
(
self
):
self
.
sock
.
listen
(
5
)
...
...
@@ -204,7 +230,9 @@ class SSHServer:
try
:
client
,
addr
=
self
.
sock
.
accept
()
print
(
'Listening for connection ...'
)
t
=
threading
.
Thread
(
target
=
self
.
handle_ssh_request
,
args
=
(
client
,
addr
))
# t = threading.Thread(target=self.handle_ssh_request, args=(client, addr))
t
=
process
.
Process
(
target
=
self
.
handle_ssh_request
,
args
=
(
client
,
addr
))
t
.
daemon
=
True
t
.
start
()
except
Exception
as
e
:
...
...
This diff is collapsed.
Click to expand it.
terminal/utils.py
View file @
ebb30424
...
...
@@ -3,6 +3,15 @@
#
import
logging
from
logging.config
import
dictConfig
from
ssh_config
import
config
,
env
CONFIG_SSH_SERVER
=
config
.
get
(
env
)
def
get_logger
(
name
):
dictConfig
(
CONFIG_SSH_SERVER
.
LOGGING
)
return
logging
.
getLogger
(
'jumpserver.
%
s'
%
name
)
This diff is collapsed.
Click to expand it.
terminal/web_server.py
→
terminal/web_s
sh_s
erver.py
View file @
ebb30424
File moved
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment