首页 文章 精选 留言 我的

精选列表

搜索[远程],共10000篇文章
优秀的个人博客,低调大师

ssh_scan:远程验证你SSH服务的配置和策略

ssh_scan 是一个面向 Linux 和 UNIX 服务器的易用的 SSH 服务参数配置和策略的扫描器程序,其思路来自Mozilla OpenSSH 安全指南,这个指南为 SSH 服务参数配置提供了一个可靠的安全策略基线的建议,如加密算法(Ciphers),报文认证信息码算法(MAC),密钥交换算法(KexAlgos)和其它。 ssh_scan 有如下好处: 它的依赖是最小化的,ssh_scan 只引入了本地 Ruby 和 BinData 来进行它的工作,没有太多的依赖。 它是可移植的,你可以在其它的项目中使用 ssh_scan 或者将它用在自动化任务上。 它是易于使用的,只需要简单的将它指向一个 SSH 服务就可以获得一个该服务所支持的选项和策略状态的 JSON 格式报告。 它同时也是易于配置的,你可以创建适合你策略需求的策略。 建议阅读:如何在 Linux 上安装配置 OpenSSH 服务 如何在 Linux 上安装 ssh_scan 有如下三种安装 ssh_scan 的方式: 使用 Ruby gem 来安装运行,如下: -----------在Debian/Ubuntu----------- $sudoapt-getinstallrubygem $sudogeminstallssh_scan -----------在CentOS/RHEL----------- #yuminstallrubyrubygem #geminstallssh_scan 使用docker 容器来运行,如下: #dockerpullmozilla/ssh_scan #dockerrun-itmozilla/ssh_scan/app/bin/ssh_scan-tgithub.com 使用源码安装运行,如下: #gitclonehttps://github.com/mozilla/ssh_scan.git #cdssh_scan #gpg2--keyserverhkp://keys.gnupg.net--recv-keys409B6B1796C275462A1703113804BB82D39DC0E3 #curl-sSLhttps://get.rvm.io|bash-sstable #rvminstall2.3.1 #rvmuse2.3.1 #geminstallbundler #bundleinstall #./bin/ssh_scan 如何在 Linux 上使用 ssh_scan 使用 ssh_scan 的语法如下: $ssh_scan-tip地址 $ssh_scan-t主机名 举个例子来扫描 192.168.43.198 这台服务器的 SSH 配置和策略,键入: $ssh_scan-t192.168.43.198 注意你同时也可以像下方展示的给 -t 选项传入一个[IP地址/地址段/主机名]: $ssh_scan-t192.168.43.198,200,205 $ssh_scan-ttest.tecmint.lan 输出示例: I,[2017-05-09T10:36:17.913644#7145]INFO--:You'reusingthelatestversionofssh_scan0.0.19 [ { "ssh_scan_version":"0.0.19", "ip":"192.168.43.198", "port":22, "server_banner":"SSH-2.0-OpenSSH_7.2p2Ubuntu-4ubuntu2.1", "ssh_version":2.0, "os":"ubuntu", "os_cpe":"o:canonical:ubuntu:16.04", "ssh_lib":"openssh", "ssh_lib_cpe":"a:openssh:openssh:7.2p2", "cookie":"68b17bcca652eeaf153ed18877770a38", "key_algorithms":[ "curve25519-sha256@libssh.org", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group-exchange-sha256", "diffie-hellman-group14-sha1" ], "server_host_key_algorithms":[ "ssh-rsa", "rsa-sha2-512", "rsa-sha2-256", "ecdsa-sha2-nistp256", "ssh-ed25519" ], "encryption_algorithms_client_to_server":[ "chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com" ], "encryption_algorithms_server_to_client":[ "chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "aes256-gcm@openssh.com" ], "mac_algorithms_client_to_server":[ "umac-64-etm@openssh.com", "umac-128-etm@openssh.com", "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha1-etm@openssh.com", "umac-64@openssh.com", "umac-128@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1" ], "mac_algorithms_server_to_client":[ "umac-64-etm@openssh.com", "umac-128-etm@openssh.com", "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha1-etm@openssh.com", "umac-64@openssh.com", "umac-128@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1" ], "compression_algorithms_client_to_server":[ "none", "zlib@openssh.com" ], "compression_algorithms_server_to_client":[ "none", "zlib@openssh.com" ], "languages_client_to_server":[ ], "languages_server_to_client":[ ], "hostname":"tecmint", "auth_methods":[ "publickey", "password" ], "fingerprints":{ "rsa":{ "known_bad":"false", "md5":"0e:d0:d7:11:f0:9b:f8:33:9c:ab:26:77:e5:66:9e:f4", "sha1":"fc:8d:d5:a1:bf:52:48:a6:7e:f9:a6:2f:af:ca:e2:f0:3a:9a:b7:fa", "sha256":"ff:00:b4:a4:40:05:19:27:7c:33:aa:db:a6:96:32:88:8e:bf:05:a1:81:c0:a4:a8:16:01:01:0b:20:37:81:11" } }, "start_time":"2017-05-0910:36:17+0300", "end_time":"2017-05-0910:36:18+0300", "scan_duration_seconds":0.221573169, "duplicate_host_key_ips":[ ], "compliance":{ "policy":"MozillaModern", "compliant":false, "recommendations":[ "RemovetheseKeyExchangeAlgos:diffie-hellman-group14-sha1", "RemovetheseMACAlgos:umac-64-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,hmac-sha1", "RemovetheseAuthenticationMethods:password" ], "references":[ "https://wiki.mozilla.org/Security/Guidelines/OpenSSH" ] } } ] 你可以使用 -p 选项来指定不同的端口,-L 选项来开启日志记录配合 -V 选项来指定日志级别: $ssh_scan-t192.168.43.198-p22222-Lssh-scan.log-VINFO 另外,可以使用 -P 或 --policy 选项来指定一个策略文件(默认是 Mozilla Modern)(LCTT 译注:这里的 Modern 可能指的是 https://wiki.mozilla.org/Security/Server_Side_TLS 中提到的 Modern compatibility ): $ssh_scan-t192.168.43.198-Lssh-scan.log-VINFO-P/path/to/custom/policy/file ssh_scan 使用帮助与其它示例: $ssh_scan-h 输出示例: ssh_scanv0.0.17(https://github.com/mozilla/ssh_scan) Usage:ssh_scan[options] -t,--target[IP/Range/Hostname]IP/Ranges/Hostnametoscan -f,--file[FilePath]FilePathofthefilecontainingIP/Range/Hostnamestoscan -T,--timeout[seconds]Timeoutperconnectafterwhichssh_scangivesuponthehost -L,--logger[LogFilePath]Enablelogger -O,--from_json[FilePath]FiletoreadJSONoutputfrom -o,--output[FilePath]FiletowriteJSONoutputto -p,--port[PORT]Port(Default:22) -P,--policy[FILE]Custompolicyfile(Default:MozillaModern) --threads[NUMBER]Numberofworkerthreads(Default:5) --fingerprint-db[FILE]Filelocationoffingerprintdatabase(Default:./fingerprints.db) --suppress-update-statusDonotcheckforupdates -u,--unit-test[FILE]Throwappropriateexitcodesbasedoncompliancestatus -V[STD_LOGGING_LEVEL], --verbosity -v,--versionDisplayjustversioninfo -h,--helpShowthismessage Examples: ssh_scan-t192.168.1.1 ssh_scan-tserver.example.com ssh_scan-t::1 ssh_scan-t::1-T5 ssh_scan-fhosts.txt ssh_scan-ooutput.json ssh_scan-Ooutput.json-orescan_output.json ssh_scan-t192.168.1.1-p22222 ssh_scan-t192.168.1.1-p22222-Loutput.log-VINFO ssh_scan-t192.168.1.1-Pcustom_policy.yml ssh_scan-t192.168.1.1--unit-test-Pcustom_policy.yml 作者:Aaron Kili 来源:51CTO

优秀的个人博客,低调大师

Linux Shell脚本之远程自动化部署java maven项目

脚本功能: 检查运行环境(包括运行权限、网络、DNS解析等),自动从git上获取java maven项目工程源码,在机器A上build,build完成后,备份机器B上原有的配置文件(如果存在),将Class、Lib文件和备份的配置文件等上传到机器B,重新启动机器B上的服务以便变更生效。 脚本特点: 1.(与之前的自动部署脚本相比)全新优化了脚本代码,更friendly,结构更紧凑、逻辑更加严谨 2.Public header删除了无用或者不好用的有色彩显示函数,并修正了WORKDIR不是绝对路径可能导致的bug 3.修正了域名解析判断是否正常的一个bug,该bug可能导致遇到无法解析后不断尝试解析 4.全新的通用main函数,自带文件锁和自动接受处理INT、TERM、EXIT进程信号,整个脚本更加的模块化和标准化 5.针对项目方面,增加了对java项目配置文件的备份和还原功能,增加了对docker容器的支持 使用办法: 将脚本上传到Linux任意目录,至少修改三个变量(分别是项目源码的git地址、部署对象的IP、部署对象的目标目录): project_clone="ssh://git@xxx/xxx.git" deploy_target_host_ip="xxx.xxx.xxx.xxx" project_top_directory_to_target_host="/path/to/deploy/project" 如果此项目依赖于其他项目,则修改“project_clone_depends_1”变量,如果要想使部署后自动生效,则,可以将启动脚本放在项目git源码下的bin目录下,默认名称为“startup.sh” 如果此项目部署在目标主机的docker容器内,则修改“docker_container_name”变量,以便重启容器生效。 多个容器启动的依赖关系的处理已经在TODO计划中。 首次执行需要将配置文件准确的写入项目文件中,一次写入后期无须修改,如需修改,直接修改部署对象主机上的配置文件即可。 在任意位置使用下方命令运行即可,脚本一旦运行一次,自动添加可执行权限,无须手动添加。 bash/path/to/this.sh 可以从GitHub上获取最新脚本内容:https://github.com/DingGuodong/AutomaticDeployJavaMavenProject 脚本内容: #!/bin/bash #Name:doDeploy.sh #ExecutethisshellscripttodeployJavaprojectsbuiltbyMavenautomaticallyonremotehosts. #debugoption #_XTRACE_FUNCTIONS=$(set+o|grepxtrace) #set-oxtrace #defineuserfriendlymessages header=" Function:ExecutethisshellscripttodeployJavaprojectsbuiltbyMavenautomaticallyonremotehosts. License:Opensourcesoftware " #definevariables #Wheretogetsourcecode project_clone_depends_1="" project_clone="ssh://git@xxx/xxx.git" deploy_target_host_ip="xxx.xxx.xxx.xxx" project_top_directory_to_target_host="/path/to/deploy/project" docker_container_name="" #Settinghowmanydaysdoyouwantsaveoldreleases,defaultis10days save_old_releases_for_days=10 #enddefinevariables #pretreatment test-z${project_clone_depends_1}||project_clone_target_depends_1="`echo${project_clone_depends_1}|awk-F'[/.]+''{print$(NF-1)}'`" project_clone_target="`echo${project_clone}|awk-F'[/.]+''{print$(NF-1)}'`" project_clone_repository_name=${project_clone_target} #endpretreatment #Publicheader #============================================================================================================================= #resolvelinks-$0maybeasymboliclink #learnfromapache-tomcat-6.x.xx/bin/catalina.sh PRG="$0" while[-h"$PRG"];do ls=`ls-ld"$PRG"` link=`expr"$ls":'.*->\(.*\)$'` ifexpr"$link":'/.*'>/dev/null;then PRG="$link" else PRG=`dirname"$PRG"`/"$link" fi done #Getstandardenvironmentvariables PRGDIR=`dirname"$PRG"` #echocolorfunction,smarter,learnfromlnmp.orglnmpinstall.sh functionecho_r(){ #Colorred:Error,Failed [$#-ne1]&&return1 echo-e"\033[31m$1\033[0m" } functionecho_g(){ #Colorgreen:Success [$#-ne1]&&return1 echo-e"\033[32m$1\033[0m" } functionecho_y(){ #Coloryellow:Warning [$#-ne1]&&return1 echo-e"\033[33m$1\033[0m" } functionecho_b(){ #Colorblue:Debug,friendlyprompt [$#-ne1]&&return1 echo-e"\033[34m$1\033[0m" } #endechocolorfunction,smarter #WORKDIR="`realpath${WORKDIR}`" WORKDIR="`readlink-f${PRGDIR}`" #endpublicheader #============================================================================================================================= USER="`id-un`" LOGNAME="$USER" if[$UID-ne0];then echo"WARNING:Runningasanon-rootuser,\"$LOGNAME\".Functionalitymaybeunavailable.Onlyrootcanusesomecommandsoroptions" fi command_exists(){ #which"$@">/dev/null2>&1 command-v"$@">/dev/null2>&1 } check_command_can_be_execute(){ [$#-ne1]&&return1 command_exists$1 } check_network_connectivity(){ echo_b"checkingnetworkconnectivity..." network_address_to_check=8.8.4.4 stable_network_address_to_check=114.114.114.114 ping_count=2 ping-c${ping_count}${network_address_to_check}>/dev/null retval=$? if[${retval}-ne0];then ifping-c${ping_count}${stable_network_address_to_check}>/dev/null;then echo_g"Networkto$stable_network_address_to_checksucceed!" echo_y"Note:networkto$network_address_to_checkfailedonce!maybejustsomepackagesloss." elif!iproute|grepdefault>/dev/null;then echo_r"Networkisunreachable,gatewayisnotset." exit1 elif!ping-c2$(iproute|awk'/default/{print$3}')>/dev/null;then echo_r"Networkisunreachable,gatewayisunreachable." exit1 else echo_r"Networkisblocked!" exit1 fi elif[${retval}-eq0];then echo_g"Checknetworkconnectivitypassed!" fi } check_name_resolve(){ echo_b"checkingDNSnameresolve..." target_name_to_resolve="github.com" stable_target_name_to_resolve="www.aliyun.com" ping_count=1 if!ping-c${ping_count}${target_name_to_resolve}>/dev/null;then echo_y"Namelookupfailedfor$target_name_to_resolvewith$ping_counttimes" ifping-c${ping_count}${stable_target_name_to_resolve}>/dev/null;then echo_g"Namelookupsuccessfor$stable_target_name_to_resolvewith$ping_counttimes" fi eval_md5sum_of_nameserver_config="`md5sum/etc/resolv.conf|awk'{print$1}'`" iftest${eval_md5sum_of_nameserver_config}="674ea91675cdfac353bffbf49dc593c3";then echo_y"Nameserverconfigfileisvalidated,butnamelookupfailedfor$target_name_to_resolvewith$ping_counttimes" return0 fi [-f/etc/resolv.conf]&&cp/etc/resolv.conf/etc/resolv.conf_$(date+%Y%m%d%H%M%S)~ cat>/etc/resolv.conf<<eof nameserver114.114.114.114 nameserver8.8.4.4 eof check_name_resolve else echo_g"CheckDNSnameresolvepassed!" return0 fi } functioncheckOtherDependencies(){ echo_b"Checkingotherdependenciesfordeployprocedure..." echo_b"\tCheckingusercustomizedvariables..." #Refer: #if[-z${var+x}];then #echo"varisunset";elseecho"varissetto'$var'" #fi #if["$varx"="x"];then #echo"varisempty";elseecho"varissetto'$var'" #fi #if[-z$var];then #echo"varisempty";elseecho"varissetto'$var'" #fi if[[-z${project_clone}]];then echo_r"Error:project_cloneisundefined!" exit1 elif[[-z${deploy_target_host_ip}]];then echo_r"Error:deploy_target_host_ipisundefined!" exit1 elif[[-z${project_top_directory_to_target_host}]];then echo_r"Error:project_top_directory_to_target_hostisundefined!" exit1 fi echo_g"\tCheckingusercustomizedvariablespassed!" echo_b"\tCheckingdiskspaceavailable..." disk_space_available=`df${WORKDIR}|tail-n1|awk'{print$(NF-2)}'` if[[${disk_space_available}-lt2097152]];then echo_y"Warning:Diskspaceof$WORKDIRissmallerthan2GB" #exit1 else echo_g"\tCheckingdiskspaceavailablepassed!" fi echo_g"Allrequireddependenciescheckpassed!" } functionsetDirectoryStructureOnLocalHost(){ if[-f${WORKDIR}/.capistrano_ds_lock];then echo_g"Setdirectorystructurehasbeendone,skipping." return fi echo_b"Settingdirectorystructure..." #learnfromcapistrano #Refer:http://capistranorb.com/documentation/getting-started/structure/ #Refer:http://capistranorb.com/documentation/getting-started/structure/# #├──current->/var/www/my_app_name/releases/20150120114500/ #├──releases #│├──20150080072500 #│├──20150090083000 #│├──20150100093500 #│├──20150110104000 #│└──20150120114500 #├──repo #│└──<VCSrelateddata> #├──revisions.log #└──shared #└──<linked_filesandlinked_dirs> #currentisasymlinkpointingtothelatestrelease.Thissymlinkisupdatedattheendofasuccessfuldeployment.Ifthedeploymentfailsinanystepthecurrentsymlinkstillpointstotheoldrelease. #releasesholdsalldeploymentsinatimestampedfolder.Thesefoldersarethetargetofthecurrentsymlink. #repoholdstheversioncontrolsystemconfigured.Incaseofagitrepositorythecontentwillbearawgitrepository(e.g.objects,refs,etc.). #revisions.logisusedtologeverydeployorrollback.Eachentryistimestampedandtheexecutinguser(usernamefromlocalmachine)islisted.DependingonyourVCSdatalikebranchnamesorrevisionnumbersarelistedaswell. #sharedcontainsthelinked_filesandlinked_dirswhicharesymlinkedintoeachrelease.Thisdatapersistsacrossdeploymentsandreleases.Itshouldbeusedforthingslikedatabaseconfigurationfilesandstaticandpersistentuserstoragehandedoverfromonereleasetothenext. #Theapplicationiscompletelycontainedwithinthepathof:deploy_to.Ifyouplanondeployingmultipleapplicationstothesameserver,simplychooseadifferent:deploy_topath. #Checkdirectoriesfordeploy [!-d${WORKDIR}/release]&&mkdir${WORKDIR}/release [!-d${WORKDIR}/repository]&&mkdir${WORKDIR}/repository [!-d${WORKDIR}/share]&&mkdir${WORKDIR}/share #enddirectoriesstructure #Additionaldirectoriesstructureforfulldeployoperation #forbackupremotehostconfigfile [!-d${WORKDIR}/backup]&&mkdir${WORKDIR}/backup #setadirectoriesstructurelock touch${WORKDIR}/.capistrano_ds_lock echo_g"Setdirectorystructuresuccessfully!" } functioncleanOldReleases(){ save_days=${save_old_releases_for_days:-10} if[!-d${WORKDIR}/release];then echo_b"CanNOTfindreleasedirectory,skipping." return fi need_clean=$(find${WORKDIR}/release-mtime+${save_days}-execls'{}'\;) if[!-z${need_clean}];then echo_g"Expiredreleasesfoundandwillberemovedfromproject!" find${WORKDIR}/release-mtime+${save_days}-execrm-rf'{}'\; if[$?-eq0];then echo_g"Expiredreleaseshaveremovedfromproject!" else echo_r"CanNOTremoveexpiredreleases,pleasealtertoAdminusers." fi else echo_g"Allreleasesarenotexpired,skipping." fi } #git_project_clonerepositorybranch functiongit_project_clone(){ set-oerrexit [$#-ge1]&&project_clone_repository="$1" project_clone_repository_name="`echo${project_clone_repository}|awk-F'[/.]+''{print$(NF-1)}'`" project_clone_directory=${WORKDIR}/repository/${project_clone_repository_name} iftest-n$2;then branch="$2" else branch="develop" fi iftest!-d${project_clone_directory};then echo_b"gitclonefrom$project_clone_repository" gitclone${project_clone_repository}${project_clone_directory}>>${WORKDIR}/git_$(date+%Y%m%d)_$$.log2>&1 #TODO(GuodongDing)getbranchnamesorrevisionnumbersfromVCSdata cd${project_clone_directory} gitcheckout${branch}>>${WORKDIR}/git_$(date+%Y%m%d)_$$.log2>&1 cd.. echo_g"gitclonefrom$project_clone_repositorysuccessfully!" else echo_b"gitpullfrom$project_clone_repository" cd${project_clone_directory} gitpull>>${WORKDIR}/git_$(date+%Y%m%d)_$$.log2>&1 gitcheckout${branch}>>${WORKDIR}/git_$(date+%Y%m%d)_$$.log2>&1 #TODO(GuodongDing)getbranchnamesorrevisionnumbersfromVCSdata cd.. echo_g"gitpullfrom$project_clone_repositorysuccessfully!" fi set+oerrexit } functionmaven_build_project_deprecated(){ set-oerrexit echo_b"Domvnbuildjavaproject..." check_command_can_be_executemvn [$#-ge1]&&project_clone_repository="$1" project_clone_repository_name="`echo${project_clone_repository}|awk-F'[/.]+''{print$(NF-1)}'`" project_clone_directory=${WORKDIR}/repository/${project_clone_repository_name} cd${project_clone_directory} mvninstall>>${WORKDIR}/mvn_build_$(date+%Y%m%d)_$$.log2>&1 mvncleanpackage>>${WORKDIR}/mvn_build_$(date+%Y%m%d)_$$.log2>&1 cd.. echo_g"Domvnbuildjavaprojectfinishedwithexitcode0!" set+oerrexit } functionmaven_build_project(){ echo_b"Domvnbuildjavaprojectfor`echo$1|awk-F'[/.]+''{print$(NF-1)}'`..." check_command_can_be_executemvn [$#-ge1]&&project_clone_repository="$1" project_clone_repository_name="`echo${project_clone_repository}|awk-F'[/.]+''{print$(NF-1)}'`" project_clone_directory=${WORKDIR}/repository/${project_clone_repository_name} cd${project_clone_directory} mvninstall>>${WORKDIR}/mvn_build_$(date+%Y%m%d)_$$.log2>&1 retval=$? if[${retval}-ne0];then echo_r"mvninstallfailed!Moredetailsreferto${WORKDIR}/mvn_build_$(date+%Y%m%d)_$$.log" exit1 else echo_g"mvninstallfor${project_clone_repository_name}successfully!" fi mvncleanpackage>>${WORKDIR}/mvn_build_$(date+%Y%m%d)_$$.log2>&1 retval=$? if[${retval}-ne0];then echo_r"mvncleanpackagefor${project_clone_repository_name}failed!Moredetailsreferto${WORKDIR}/mvn_build_$(date+%Y%m%d)_$$.log" exit1 else echo_g"mvncleanpackagefor${project_clone_repository_name}successfully!" fi cd.. echo_g"Domvnbuildjavaprojectfinishedfor${project_clone_repository_name}withexitcode0!" } functioncheck_ssh_can_be_connect(){ [$#-ne1]&&return1 echo_b"Checkifcansshtoremotehost$1..." check_command_can_be_executessh||return1 ssh-i/etc/ssh/ssh_host_rsa_key-p22-oStrictHostKeyChecking=noroot@$1"uname-a>/dev/null2>&1" retval=$? if[${retval}-ne0];then echo_r"Checksshtoremotehost$1failed!" exit1 else echo_g"Checksshtoremotehost$1successfully!" fi } #ssh_execute_command_on_remote_hosthostnamecommand functionssh_execute_command_on_remote_host(){ [$#-ne2]&&return1 ssh-i/etc/ssh/ssh_host_rsa_key-p22-oStrictHostKeyChecking=noroot@$1"$2">>${WORKDIR}/ssh_command_$(date+%Y%m%d)_$$.log retval=$? if[${retval}-ne0];then echo_r"sshexecutecommandonremotehost$2failed!Moredetailsreferto${WORKDIR}/ssh_command_$(date+%Y%m%d)_$$.log" return1 else echo_g"sshexecutecommandonremotehost$2successfully!" return0 fi } functionrestart_docker_container(){ echo_b"Restartingdockercontainer..." [$#-ne1]&&return1 #TODO(GuodongDing)ifweneedrestartmorerelateddockercontainer localdocker_container_name="" test-n$1&&docker_container_name="$1" ssh_execute_command_on_remote_host"dockerrestart$docker_container_name" retval=$? if[${retval}-ne0];then echo_r"restartdockercontainerfor$docker_container_namefailed!" exit1 else echo_g"restartdockercontainerfor$docker_container_namesuccessfully!" return0 fi } #scp_local_files_to_remote_hostlocal_pathremote_hostnameremote_path functionscp_local_files_to_remote_host(){ [$#-ne3]&&return1 [!-d$1-a!-f$1]&&return1 check_ssh_can_be_connect$2 scp-i/etc/ssh/ssh_host_rsa_key-P22-oStrictHostKeyChecking=no-rp$1root@$2:$3>/dev/null2>&1 retval=$? if[${retval}-ne0];then echo_r"scplocalfilestoremotehostfailed!" exit1 else echo_g"scplocalfilestoremotehostsuccessfully!" fi } #scp_remote_files_to_local_hostremote_hostnameremote_pathlocal_path functionscp_remote_files_to_local_host(){ [$#-ne3]&&return1 check_ssh_can_be_connect$1 scp-i/etc/ssh/ssh_host_rsa_key-P22-oStrictHostKeyChecking=no-rproot@$1:$2$3>/dev/null2>&1 retval=$? if[${retval}-ne0];then echo_r"scpremotefilestolocalhostfailed!" exit1 else echo_g"scpremotefilestolocalhostsuccessfully!" fi } functionbackup_remote_host_config_files(){ echo_b"backupremotehostconfigfiles..." scp_remote_files_to_local_host${deploy_target_host_ip}${project_top_directory_to_target_host}/*${WORKDIR}/backup #getconfigfiles ["$(ls-A${WORKDIR}/backup)"]&&find${WORKDIR}/backup/.-typef!-name.-a!-name'*.xml*'-a!-name'*.properties*'-execrm-f--'{}'\; #removeemptydirectory find${WORKDIR}/backup/.-empty-typed-delete #TODO(GuodongDing)improvementshere echo_g"backupremotehostconfigfilesfinished." } functionrollback_remote_host_config_files(){ echo_b"rollbackremotehostconfigfiles..." #scp_local_files_to_remote_host${WORKDIR}/backup${deploy_target_host_ip}${project_top_directory_to_target_host} saved_IFS=$IFS IFS='' cd${WORKDIR}/current forfilein${WORKDIR}/backup/*;do scp_local_files_to_remote_host${file}${deploy_target_host_ip}${project_top_directory_to_target_host} done cd${WORKDIR} IFS=${saved_IFS} #TODO(GuodongDing)ifsaveremotehostconfigfiles #someops #TODO(GuodongDing)improvementshere echo_g"rollbackremotehostconfigfilesfinished." } functiondeploy(){ [-n"$header"]&&echo"$header" #checkadirectorieslock,Note:thisisredundant if[[!-f${WORKDIR}/.lock]];then setDirectoryStructureOnLocalHost fi cleanOldReleases #dodependencieschecking check_network_connectivity check_name_resolve checkOtherDependencies check_ssh_can_be_connect${deploy_target_host_ip} #docorejob #TODO(GuodongDing)ifweneedagit_project_clone"$project_clone_depends_1"hereusingautojudgmentstatement test-z${project_clone_depends_1}||git_project_clone"$project_clone_depends_1" git_project_clone"$project_clone" test-z${project_clone_depends_1}||maven_build_project"$project_clone_depends_1" maven_build_project"$project_clone" cd${WORKDIR} #links_target_directory_to_current #Makedirectorytoreleasedirectory iftest!-d${WORKDIR}/release-o!-d${WORKDIR}/share;then echo_r"capistranodirectorystructureisbroken,makesurethefile.capistrano_ds_lockisdeletedbeforeanewdeploy!" exit1 #test-f${WORKDIR}/.capistrano_ds_lock&&\rm-rf${WORKDIR}/.capistrano_ds_lock fi new_release_just_created="$WORKDIR/release/$(date+%Y%m%d%H%M%S)" [!-d${new_release_just_created}]&&mkdir${new_release_just_created} [-d${WORKDIR}/repository/${project_clone_repository_name}/target/${project_clone_repository_name}/]&&\ \cp-rf${WORKDIR}/repository/${project_clone_repository_name}/target/${project_clone_repository_name}/*${new_release_just_created} #Makesourcecodesymboliclinktocurrent ([-f${WORKDIR}/current]||[-d${WORKDIR}/current])&&rm-rf${WORKDIR}/current ln-s${new_release_just_created}${WORKDIR}/current #backupremotehostconfigfiles backup_remote_host_config_files #scp_local_files_to_remote_host${WORKDIR}/current/${deploy_target_host_ip}${project_top_directory_to_target_host} saved_IFS=$IFS IFS='' cd${WORKDIR}/current forfilein${WORKDIR}/current/*;do scp_local_files_to_remote_host${file}${deploy_target_host_ip}${project_top_directory_to_target_host} done cd${WORKDIR} IFS=${saved_IFS} #rollbackremotehostconfigfiles rollback_remote_host_config_files #Moveconfandlogsdirectivesfromreleasetoshare [-d${WORKDIR}/release/conf]&&mv${WORKDIR}/release/conf${WORKDIR}/share/conf [-d${WORKDIR}/release/logs]&&mv${WORKDIR}/release/logs${WORKDIR}/share/logs #Makeconfandlogssymboliclinktocurrent [-d${WORKDIR}/share/conf]&&ln-s${WORKDIR}/share/conf${WORKDIR}/current/conf [-d${WORKDIR}/share/logs]&&ln-s${WORKDIR}/share/logs${WORKDIR}/current/logs #Startserviceorvalidatestatus if[[-e${WORKDIR}/current/bin/startup.sh]];then ${WORKDIR}/current/bin/startup.shstart RETVAL=$? else #TODO(GuodongDing)externalhealthcheck test-z${docker_container_name}||restart_docker_container${docker_container_name} RETVAL=$? fi #ifstartedok,thencreateaworkableprogramtoafile if[[${RETVAL}-eq0]];then #Notecatwitheofmuststartatrow0,andwitheofendonly,suchasnoblankspaces,etc cat>${WORKDIR}/share/workable_program.log<<eof ${new_release_just_created} eof echo_g"Deploysuccessfully!" echo_g"currentworkableversionis$(cat${WORKDIR}/share/workable_program.log)" #ls--color=auto-l${WORKDIR}/current #ls--color=auto-l${WORKDIR}/current/ else echo_r"Error:Deployfailed!" ${WORKDIR}/`basename$0`rollback fi } #Rollbacktolastrightconfiguration functionrollback(){ [-n"$header"]&&echo"$header" echo_b"Rollbacktolastrightconfiguration..." #Thekeyisfindlastfileswhichcanwork WORKABLE_PROGRAM=`cat${WORKDIR}/share/workable_program.log` if[[-z${WORKABLE_PROGRAM}]];then echo_r"Error:CanNOTfindworkablereleaseversion!Pleasecheckifitisfirstdeployment!" exit1 fi #Stopserviceifwehave if[[-e${WORKDIR}/current/bin/startup.sh]];then ${WORKDIR}/current/bin/startup.shstop fi #Removefaileddeploy rm-rf${WORKDIR}/current #Remakesourcecodesymboliclinktocurrent ln-s${WORKABLE_PROGRAM}${WORKDIR}/current #Remakeconfandlogssymboliclinktocurrent [-d${WORKDIR}/share/conf]&&ln-s${WORKDIR}/share/conf${WORKDIR}/current [-d${WORKDIR}/share/logs]&&ln-s${WORKDIR}/share/logs${WORKDIR}/current #Startserviceorvalidatestatus if[[-e${WORKDIR}/current/bin/startup.sh]];then ${WORKDIR}/current/bin/startup.shstart RETVAL=$? else #TODO(GuodongDing)externalhealthcheck test-z${docker_container_name}||restart_docker_container${docker_container_name} RETVAL=$? fi #ifstartedok,thencreateaworkableprogramtoafile if[[${RETVAL}-eq0]];then echo_g"Rollbacksuccessfully!" echo_g"currentworkableversionis$WORKABLE_PROGRAM" #ls--color=auto-l${WORKDIR}/current fi } functiondestroy(){ [-n"$header"]&&echo"$header" #echoaWarningmessage echo_y"Warning:Thisactionwilldestroyallthisproject,andthisisunrecoverable!" answer="n" echo_y"Doyouwanttodestroythisproject?" read-p"(Defaultno,ifyouwantpleaseinput:y,ifnotpleasepresstheenterbutton):"answer case"$answer"in y|Y|Yes|YES|yes|yES|yEs|YeS|yeS) #deleteallfileexpectforthisscriptself #find:warning:Unixfilenamesusuallydon'tcontainslashes(thoughpathnamesdo).Thatmeansthat'-name`./deploy.sh''willprobablyevaluatetofalseallthetimeonthissystem.Youmightfindthe'-wholename'testmoreuseful,orperhaps'-samefile'.Alternatively,ifyouareusingGNUgrep,youcoulduse'find...-print0|grep-FzZ`./deploy.sh''. #echo$WORKDIR/ #find-L$WORKDIR-typef!-name"$(basename$0)"-execls--color=auto-al{}\; #find-L.-typef!-name"deploy.sh"-execls--color=auto-al{}\; #find-L.-typed-execls--color=auto-al{}\; #find-L./-maxdepth1!-name"deploy.sh"!-wholename"./" #ls|grep-v"filename"|xargsrm-rf find-L${WORKDIR}-maxdepth1!-name"$(basename$0)"!-wholename"$WORKDIR"-execrm-rf'{}'\; if[$?-eq0];then test-f${WORKDIR}/.capistrano_ds_lock&&\rm-rf${WORKDIR}/.capistrano_ds_lock echo_g"Destroythisprojectsuccessfully!Nowwillexitwithstatus0." exit0 else echo_r"Error:somethinggowrong!PleasecheckoraltertoAdminuser!" exit1 fi ;; n|N|No|NO|no|nO) echo_g"destroyactioniscancel" exit0 ;; *) echo_r"Areyoukiddingme?Youareabadkid!" exit1 ;; esac } functionmain(){ lock_filename="lock_$$_$RANDOM" #lock_filename_full_path="/var/lock/subsys/$lock_filename" lock_filename_full_path="/var/lock/$lock_filename" if(set-onoclobber;echo"$$">"$lock_filename_full_path")2>/dev/null;then trap'rm-f"$lock_filename_full_path";exit$?'INTTERMEXIT #Justatestforcallitself,commentit if[[$#-ne1]];then #$0deploy [!-x${WORKDIR}/`basename$0`]&&chmod+x${WORKDIR}/`basename$0` ${WORKDIR}/`basename$0`deploy exit0 fi case$1in deploy) deploy ;; rollback) rollback ;; destroy) destroy ;; help|*) echo"Usage:$0{deploy|rollback|destroy}with$0itself" exit1 ;; esac rm-f"$lock_filename_full_path" trap-INTTERMEXIT else echo"Failedtoacquirelock:$lock_filename_full_path" echo"heldby$(cat${lock_filename_full_path})" fi } main$@ #debugoption #${_XTRACE_FUNCTIONS} 运行效果: 可以尝试使用Chrome浏览器打开该页面,右键单击,选择“在新标签页中打开图片”查看清晰大图。 推荐Windows用户使用PyCharm(5.0.x)结合Bash Support插件编辑bash shell script文件。 注:由于该脚本的大幅度更新,因此最新的运行效果图可以自行运行观察。 --end--

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。