| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981 |
- #!/bin/bash
- RED='\033[0;31m'
- CYAN='\033[0;36m'
- YELLOW='\033[0;33m'
- NC='\033[0m'
- disable_option=false
- enable_ech=false
- listen_port=""
- override_port=""
- ip_v4=""
- ip_v6=""
- record_content=""
- record_type=""
- record_name=""
- obfs_password=""
- domain=""
- domain_name=""
- up_mbps=""
- down_mbps=""
- certificate_path=""
- private_key_path=""
- public_key=""
- private_key=""
- multiplex_config=""
- brutal_config=""
- ech_key=()
- ech_config=()
- user_names=()
- user_passwords=()
- user_uuids=()
- ss_passwords=()
- stls_passwords=()
- short_ids=()
- function check_firewall_configuration() {
- local os_name=$(uname -s)
- local firewall
- if [[ $os_name == "Linux" ]]; then
- if command -v ufw >/dev/null 2>&1 && ufw status | grep -q "Status: active"; then
- firewall="ufw"
- elif command -v ip6tables >/dev/null 2>&1 && ip6tables -S | grep -q "INPUT -j DROP"; then
- firewall="ip6tables"
- elif command -v iptables >/dev/null 2>&1 && iptables -S | grep -q "INPUT -j DROP"; then
- firewall="iptables"
- elif systemctl is-active --quiet netfilter-persistent; then
- firewall="iptables-persistent"
- elif systemctl is-active --quiet iptables.service; then
- firewall="iptables-service"
- elif command -v firewalld >/dev/null 2>&1 && firewall-cmd --state | grep -q "running"; then
- firewall="firewalld"
- fi
- fi
- if [[ -z $firewall ]]; then
- echo "No firewall configuration detected or firewall is not enabled, skipping firewall configuration."
- return
- fi
- echo "Checking firewall configuration..."
- case $firewall in
- ufw)
- if ! ufw status | grep -q "Status: active" 2>/dev/null; then
- ufw enable > /dev/null 2>&1
- fi
- if ! ufw status | grep -q " $listen_port" 2>/dev/null; then
- ufw allow "$listen_port" > /dev/null 2>&1
- fi
- if ! ufw status | grep -q " $override_port" 2>/dev/null; then
- ufw allow "$override_port" > /dev/null 2>&1
- fi
- if ! ufw status | grep -q " $fallback_port" 2>/dev/null; then
- ufw allow "$fallback_port" > /dev/null 2>&1
- fi
-
- if ! ufw status | grep -q " 80" 2>/dev/null; then
- ufw allow 80 > /dev/null 2>&1
- fi
- echo "Firewall configuration has been updated."
- ;;
- iptables | iptables-persistent | iptables-service)
- if ! iptables -C INPUT -p tcp --dport "$listen_port" -j ACCEPT >/dev/null 2>&1; then
- iptables -A INPUT -p tcp --dport "$listen_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! iptables -C INPUT -p udp --dport "$listen_port" -j ACCEPT >/dev/null 2>&1; then
- iptables -A INPUT -p udp --dport "$listen_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! iptables -C INPUT -p tcp --dport "$override_port" -j ACCEPT >/dev/null 2>&1; then
- iptables -A INPUT -p tcp --dport "$override_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! iptables -C INPUT -p udp --dport "$override_port" -j ACCEPT >/dev/null 2>&1; then
- iptables -A INPUT -p udp --dport "$override_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! iptables -C INPUT -p tcp --dport "$fallback_port" -j ACCEPT >/dev/null 2>&1; then
- iptables -A INPUT -p tcp --dport "$fallback_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! iptables -C INPUT -p udp --dport "$fallback_port" -j ACCEPT >/dev/null 2>&1; then
- iptables -A INPUT -p udp --dport "$fallback_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! iptables -C INPUT -p tcp --dport 80 -j ACCEPT >/dev/null 2>&1; then
- iptables -A INPUT -p tcp --dport 80 -j ACCEPT > /dev/null 2>&1
- fi
- if ! iptables -C INPUT -p udp --dport 80 -j ACCEPT >/dev/null 2>&1; then
- iptables -A INPUT -p udp --dport 80 -j ACCEPT > /dev/null 2>&1
- fi
- if ! ip6tables -C INPUT -p tcp --dport "$listen_port" -j ACCEPT >/dev/null 2>&1; then
- ip6tables -A INPUT -p tcp --dport "$listen_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! ip6tables -C INPUT -p udp --dport "$listen_port" -j ACCEPT >/dev/null 2>&1; then
- ip6tables -A INPUT -p udp --dport "$listen_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! ip6tables -C INPUT -p tcp --dport "$override_port" -j ACCEPT >/dev/null 2>&1; then
- ip6tables -A INPUT -p tcp --dport "$override_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! ip6tables -C INPUT -p udp --dport "$override_port" -j ACCEPT >/dev/null 2>&1; then
- ip6tables -A INPUT -p udp --dport "$override_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! ip6tables -C INPUT -p tcp --dport "$fallback_port" -j ACCEPT >/dev/null 2>&1; then
- ip6tables -A INPUT -p tcp --dport "$fallback_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! ip6tables -C INPUT -p udp --dport "$fallback_port" -j ACCEPT >/dev/null 2>&1; then
- ip6tables -A INPUT -p udp --dport "$fallback_port" -j ACCEPT > /dev/null 2>&1
- fi
- if ! ip6tables -C INPUT -p tcp --dport 80 -j ACCEPT >/dev/null 2>&1; then
- ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT > /dev/null 2>&1
- fi
- if ! ip6tables -C INPUT -p udp --dport 80 -j ACCEPT >/dev/null 2>&1; then
- ip6tables -A INPUT -p udp --dport 80 -j ACCEPT > /dev/null 2>&1
- fi
- if [[ -e /etc/iptables/rules.v4 ]]; then
- iptables-save > /etc/iptables/rules.v4
- elif [[ -e /etc/sysconfig/iptables ]]; then
- iptables-save > /etc/sysconfig/iptables
- fi
- if [[ -e /etc/iptables/rules.v6 ]]; then
- ip6tables-save > /etc/iptables/rules.v6
- elif [[ -e /etc/sysconfig/ip6tables ]]; then
- ip6tables-save > /etc/sysconfig/ip6tables
- fi
- echo "Firewall configuration has been updated."
- ;;
- firewalld)
- if ! firewall-cmd --zone=public --list-ports | grep -q "$listen_port/tcp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$listen_port/tcp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$listen_port/udp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$listen_port/udp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$override_port/tcp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$override_port/tcp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$override_port/udp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$override_port/udp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$fallback_port/tcp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$fallback_port/tcp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$fallback_port/udp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$fallback_port/udp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "80/tcp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port=80/tcp --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "80/udp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port=80/udp --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$listen_port/tcp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$listen_port/tcp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$listen_port/udp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$listen_port/udp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$override_port/tcp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$override_port/tcp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$override_port/udp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$override_port/udp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$fallback_port/tcp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$fallback_port/tcp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "$fallback_port/udp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port="$fallback_port/udp" --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "80/tcp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port=80/tcp --permanent > /dev/null 2>&1
- fi
- if ! firewall-cmd --zone=public --list-ports | grep -q "80/udp" 2>/dev/null; then
- firewall-cmd --zone=public --add-port=80/udp --permanent > /dev/null 2>&1
- fi
- firewall-cmd --reload
- echo "Firewall configuration has been updated."
- ;;
- esac
- }
- function create_sing_box_folders() {
- local folders=("/usr/local/etc/sing-box" "/etc/ssl/private")
- for folder in "${folders[@]}"; do
- if [[ ! -d "$folder" ]]; then
- mkdir -p "$folder"
- [ "$folder" = "/usr/local/etc/sing-box" ] && touch "$folder/config.json"
- fi
- done
- }
- function create_juicity_folder() {
- local folders=("/usr/local/etc/juicity" "/etc/ssl/private")
- for folder in "${folders[@]}"; do
- if [[ ! -d "$folder" ]]; then
- mkdir -p "$folder"
- [ "$folder" = "/usr/local/etc/juicity" ] && touch "$folder/config.json"
- fi
- done
- }
- function ensure_clash_yaml() {
- local clash_yaml="/usr/local/etc/sing-box/clash.yaml"
- if [ ! -e "$clash_yaml" ]; then
- touch "$clash_yaml"
- fi
- }
- function check_config_file_existence() {
- local config_file="/usr/local/etc/sing-box/config.json"
- if [ ! -f "$config_file" ]; then
- echo -e "${RED}sing-box 配置文件不存在,请先搭建节点!${NC}"
- exit 1
- fi
- }
- function generate_naive_random_filename() {
- local dir="/usr/local/etc/sing-box"
- local filename=""
- while true; do
- random_value=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 5 | head -n 1)
- filename="naive_client_${random_value}.json"
- if [ ! -e "${dir}/${filename}" ]; then
- touch "${dir}/${filename}"
- naive_client_filename="${dir}/${filename}"
- break
- fi
- done
- }
- function get_temp_config_file() {
- temp_file=$(mktemp)
- curl -sSL "https://api.zeroteam.top/warp?format=sing-box" > "$temp_file"
- }
- function install_sing_box() {
- if [[ -f "/usr/local/bin/sing-box" && -f "/usr/local/etc/sing-box/config.json" ]]; then
- return 1
- else
- get_local_ip
- configure_dns64
- select_sing_box_install_option
- configure_sing_box_service
- create_sing_box_folders
- fi
- }
- function configure_dns64() {
- if [[ -n $ip_v4 ]]; then
- return
- fi
- if [[ -n $ip_v6 ]]; then
- echo "Check that the machine is IPv6 single-stack network, configure DNS64..."
- sed -i '/^nameserver /s/^/#/' /etc/resolv.conf
- echo "nameserver 2001:67c:2b0::4" >> /etc/resolv.conf
- echo "nameserver 2001:67c:2b0::6" >> /etc/resolv.conf
- echo "DNS64 configuration is complete."
- fi
- }
- function enable_bbr() {
- if grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf; then
- echo "BBR is already enabled, skipping configuration."
- return
- fi
- while true; do
- read -p "是否开启 BBR (Y/N,默认N)? " -i "N" response
- response=${response:-"N"}
- if [[ $response == "y" || $response == "Y" ]]; then
- echo "Enable BBR..."
- echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
- echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
- sysctl -p > /dev/null
- echo "BBR has been enabled"
- break
- elif [[ $response == "n" || $response == "N" ]]; then
- echo "BBR will not be enabled."
- break
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function select_sing_box_install_option() {
- while true; do
- echo "请选择 sing-box 的安装方式(默认1):"
- echo "1). 下载安装 sing-box(Latest 版本)"
- echo "2). 下载安装 sing-box(Beta 版本)"
- echo "3). 编译安装 sing-box(完整功能版本)"
- read -p "请选择 [1-2]: " install_option
- install_option="${install_option:-1}"
- case $install_option in
- 1)
- install_latest_sing_box
- break
- ;;
- 2)
- install_Pre_release_sing_box
- break
- ;;
- 3)
- install_go
- compile_install_sing_box
- break
- ;;
- *)
- echo -e "${RED}无效的选择,请重新输入!${NC}"
- ;;
- esac
- done
- }
- function install_go() {
- if ! command -v go &> /dev/null; then
- echo "Downloading Go..."
- local go_arch
- case $(uname -m) in
- x86_64)
- go_arch="amd64"
- ;;
- i686)
- go_arch="386"
- ;;
- aarch64)
- go_arch="arm64"
- ;;
- armv6l)
- go_arch="armv6l"
- ;;
- *)
- echo -e "${RED}不支持的架构: $(uname -m)${NC}"
- exit 1
- ;;
- esac
- local go_version
- go_version=$(curl -sL "https://golang.org/VERSION?m=text" | grep -o 'go[0-9]\+\.[0-9]\+\.[0-9]\+')
- local go_download_url="https://go.dev/dl/$go_version.linux-$go_arch.tar.gz"
- wget -qO- "$go_download_url" | tar -xz -C /usr/local
- echo 'export PATH=$PATH:/usr/local/go/bin' | tee -a /etc/profile >/dev/null
- source /etc/profile
- go version
- echo "Go has been installed."
- else
- echo "Go is already installed, skipping installation."
- fi
- }
- function compile_install_sing_box() {
- local go_install_command="go install -v -tags \
- with_quic,\
- with_grpc,\
- with_dhcp,\
- with_wireguard,\
- with_shadowsocksr,\
- with_ech,\
- with_utls,\
- with_reality_server,\
- with_acme,\
- with_clash_api,\
- with_v2ray_api,\
- with_gvisor,\
- with_lwip \
- github.com/sagernet/sing-box/cmd/sing-box@latest"
- echo "Compiling and installing sing-box, please wait..."
- $go_install_command
- if [[ $? -eq 0 ]]; then
- mv ~/go/bin/sing-box /usr/local/bin/
- chmod +x /usr/local/bin/sing-box
- echo "sing-box has been compiled and installed successfully."
- else
- echo -e "${RED}sing-box compilation and installation failed.${NC}"
- exit 1
- fi
- }
- function install_latest_sing_box() {
- local arch=$(uname -m)
- local url="https://api.github.com/repos/SagerNet/sing-box/releases/latest"
- local download_url
- case $arch in
- x86_64|amd64)
- download_url=$(curl -s $url | grep -o "https://github.com[^\"']*linux-amd64.tar.gz")
- ;;
- armv7l)
- download_url=$(curl -s $url | grep -o "https://github.com[^\"']*linux-armv7.tar.gz")
- ;;
- aarch64|arm64)
- download_url=$(curl -s $url | grep -o "https://github.com[^\"']*linux-arm64.tar.gz")
- ;;
- amd64v3)
- download_url=$(curl -s $url | grep -o "https://github.com[^\"']*linux-amd64v3.tar.gz")
- ;;
- s390x)
- download_url=$(curl -s $url | grep -o "https://github.com[^\"']*linux-s390x.tar.gz")
- ;;
- *)
- echo -e "${RED}不支持的架构:$arch${NC}"
- return 1
- ;;
- esac
- if [ -n "$download_url" ]; then
- echo "Downloading Sing-Box..."
- wget -qO sing-box.tar.gz "$download_url" 2>&1 >/dev/null
- tar -xzf sing-box.tar.gz -C /usr/local/bin --strip-components=1
- rm sing-box.tar.gz
- chmod +x /usr/local/bin/sing-box
- echo "Sing-Box installed successfully."
- else
- echo -e "${RED}Unable to retrieve the download URL for Sing-Box.${NC}"
- return 1
- fi
- }
- function install_Pre_release_sing_box() {
- local arch=$(uname -m)
- local url="https://api.github.com/repos/SagerNet/sing-box/releases"
- local download_url
- case $arch in
- x86_64|amd64)
- download_url=$(curl -s "$url" | jq -r '.[] | select(.prerelease == true) | .assets[] | select(.browser_download_url | contains("linux-amd64.tar.gz")) | .browser_download_url' | head -n 1)
- ;;
- armv7l)
- download_url=$(curl -s "$url" | jq -r '.[] | select(.prerelease == true) | .assets[] | select(.browser_download_url | contains("linux-armv7.tar.gz")) | .browser_download_url' | head -n 1)
- ;;
- aarch64|arm64)
- download_url=$(curl -s "$url" | jq -r '.[] | select(.prerelease == true) | .assets[] | select(.browser_download_url | contains("linux-arm64.tar.gz")) | .browser_download_url' | head -n 1)
- ;;
- amd64v3)
- download_url=$(curl -s "$url" | jq -r '.[] | select(.prerelease == true) | .assets[] | select(.browser_download_url | contains("linux-amd64v3.tar.gz")) | .browser_download_url' | head -n 1)
- ;;
- s390x)
- download_url=$(curl -s "$url" | jq -r '.[] | select(.prerelease == true) | .assets[] | select(.browser_download_url | contains("linux-s390x.tar.gz")) | .browser_download_url' | head -n 1)
- ;;
- *)
- echo -e "${RED}不支持的架构:$arch${NC}"
- return 1
- ;;
- esac
- if [ -n "$download_url" ]; then
- echo "Downloading Sing-Box..."
- wget -qO sing-box.tar.gz "$download_url" 2>&1 >/dev/null
- tar -xzf sing-box.tar.gz -C /usr/local/bin --strip-components=1
- rm sing-box.tar.gz
- chmod +x /usr/local/bin/sing-box
- echo "Sing-Box installed successfully."
- else
- echo -e "${RED}Unable to get pre-release download link for Sing-Box.${NC}"
- return 1
- fi
- }
- function install_latest_juicity() {
- local arch=$(uname -m)
- case $arch in
- "arm64")
- arch_suffix="arm64"
- ;;
- "armv5")
- arch_suffix="armv5"
- ;;
- "armv6")
- arch_suffix="armv6"
- ;;
- "armv7")
- arch_suffix="armv7"
- ;;
- "mips")
- arch_suffix="mips32"
- ;;
- "mipsel")
- arch_suffix="mips32le"
- ;;
- "mips64")
- arch_suffix="mips64"
- ;;
- "mips64el")
- arch_suffix="mips64le"
- ;;
- "riscv64")
- arch_suffix="riscv64"
- ;;
- "i686")
- arch_suffix="x86_32"
- ;;
- "x86_64")
- if [ -n "$(grep avx2 /proc/cpuinfo)" ]; then
- arch_suffix="x86_64_v3_avx2"
- else
- arch_suffix="x86_64_v2_sse"
- fi
- ;;
- *)
- echo "Unsupported architecture: $arch"
- return 1
- ;;
- esac
- local github_api_url="https://api.github.com/repos/juicity/juicity/releases/latest"
- local download_url=$(curl -s "$github_api_url" | grep "browser_download_url.*$arch_suffix.zip\"" | cut -d '"' -f 4)
- local temp_dir=$(mktemp -d)
- local install_path="/usr/local/bin/juicity-server"
- echo "Downloading the latest version of juicity-server..."
- wget -P "$temp_dir" "$download_url" >/dev/null 2>&1
- unzip "$temp_dir/*.zip" -d "$temp_dir" >/dev/null 2>&1
- mv "$temp_dir/juicity-server" "$install_path" >/dev/null 2>&1
- chmod +x /usr/local/bin/juicity-server
- echo "juicity-server has been downloaded."
- rm -rf "$temp_dir"
- }
- function configure_sing_box_service() {
- echo "Configuring sing-box startup service..."
- local service_file="/etc/systemd/system/sing-box.service"
- if [[ -f $service_file ]]; then
- rm "$service_file"
- fi
- local service_config='[Unit]
- Description=sing-box service
- Documentation=https://sing-box.sagernet.org
- After=network.target nss-lookup.target
- [Service]
- CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
- AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
- ExecStart=/usr/local/bin/sing-box run -c /usr/local/etc/sing-box/config.json
- ExecReload=/bin/kill -HUP $MAINPID
- Restart=on-failure
- RestartSec=10s
- LimitNOFILE=infinity
- [Install]
- WantedBy=multi-user.target'
- echo "$service_config" >"$service_file"
- echo "sing-box startup service has been configured."
- }
- function configure_juicity_service() {
- echo "Configuring juicity startup service..."
- local service_file="/etc/systemd/system/juicity.service"
- if [[ -f $service_file ]]; then
- rm "$service_file"
- fi
- local service_config='[Unit]
- Description=juicity-server Service
- Documentation=https://github.com/juicity/juicity
- After=network.target nss-lookup.target
- [Service]
- Type=simple
- User=root
- Environment=QUIC_GO_ENABLE_GSO=true
- ExecStart=/usr/local/bin/juicity-server run -c /usr/local/etc/juicity/config.json --disable-timestamp
- Restart=on-failure
- LimitNPROC=512
- LimitNOFILE=infinity
- [Install]
- WantedBy=multi-user.target'
- echo "$service_config" >"$service_file"
- echo "juicity startup service has been configured."
- }
- function set_listen_port() {
- while true; do
- read -p "请输入监听端口 (默认443): " new_listen_port
- new_listen_port=${new_listen_port:-443}
- if [[ $new_listen_port =~ ^[1-9][0-9]{0,4}$ && $new_listen_port -le 65535 ]]; then
- check_result=$(netstat -tulpn | grep -E "\b${new_listen_port}\b")
- if [ -z "$check_result" ]; then
- echo "监听端口:$new_listen_port"
- break
- else
- echo -e "${RED}错误:端口已被占用,请选择其他端口!${NC}" >&2
- fi
- else
- echo -e "${RED}错误:端口范围1-65535,请重新输入!${NC}" >&2
- fi
- done
- listen_port="$new_listen_port"
- }
- function set_user_name() {
- while true; do
- read -p "请输入用户名 (默认随机生成): " new_user_name
- if [[ -z "$new_user_name" ]]; then
- new_user_name=$(sing-box generate rand --base64 6 2>/dev/null || openssl rand -base64 5)
- echo "用户名:$new_user_name"
- break
- elif [[ ! -z "$new_user_name" ]]; then
- break
- fi
- done
- user_names+=("$new_user_name")
- }
- function set_user_password() {
- while true; do
- read -p "请输入密码(默认随机生成): " new_user_password
- if [[ -z "$new_user_password" ]]; then
- new_user_password=$(sing-box generate rand --base64 9 2>/dev/null || openssl rand -base64 9)
- echo "密码:$new_user_password"
- break
- elif [[ ! -z "$new_user_password" ]]; then
- break
- fi
- done
- user_passwords+=("$new_user_password")
- }
- function set_ss_password() {
- while true; do
- read -p "请输入 Shadowsocks 密码(默认随机生成): " ss_user_password
- if [[ -z $ss_user_password ]]; then
- if [[ $encryption_choice == 1 || $encryption_choice == 2 ]]; then
- ss_password=$(sing-box generate rand --base64 32)
- echo "Shadowsocks 密码: $ss_password"
- else
- ss_password=$(sing-box generate rand --base64 16)
- echo "Shadowsocks 密码: $ss_password"
- fi
- ss_passwords+=("$ss_password")
- break
- elif [[ $encryption_choice == 1 || $encryption_choice == 2 ]] && [[ ${#ss_user_password} -eq 32 ]]; then
- ss_password="$ss_user_password"
- echo "Shadowsocks 密码: $ss_password"
- ss_passwords+=("$ss_password")
- break
- elif [[ $encryption_choice != 1 && $encryption_choice != 2 ]] && [[ ${#ss_user_password} -eq 16 ]]; then
- ss_password="$ss_user_password"
- echo "Shadowsocks 密码: $ss_password"
- ss_passwords+=("$ss_password")
- break
- else
- echo -e "${RED}错误:密码长度不符合要求,请重新输入!${NC}"
- fi
- done
- }
- function set_stls_password() {
- while true; do
- read -p "请输入 ShadowTLS 密码(默认随机生成): " stls_user_password
- if [[ -z $stls_user_password ]]; then
- if [[ $encryption_choice == 1 || $encryption_choice == 2 ]]; then
- stls_password=$(sing-box generate rand --base64 32)
- echo "ShadowTLS 密码: $stls_password"
- else
- stls_password=$(sing-box generate rand --base64 16)
- echo "ShadowTLS 密码: $stls_password"
- fi
- stls_passwords+=("$stls_password")
- break
- elif [[ $encryption_choice == 1 || $encryption_choice == 2 ]] && [[ ${#stls_user_password} -eq 32 ]]; then
- stls_password="$stls_user_password"
- echo "ShadowTLS 密码: $stls_password"
- stls_passwords+=("$stls_password")
- break
- elif [[ $encryption_choice != 1 && $encryption_choice != 2 ]] && [[ ${#stls_user_password} -eq 16 ]]; then
- stls_password="$stls_user_password"
- echo "ShadowTLS 密码: $stls_password"
- stls_passwords+=("$stls_password")
- break
- else
- echo -e "${RED}错误:密码长度不符合要求,请重新输入!${NC}"
- fi
- done
- }
- function set_up_speed() {
- while true; do
- read -p "请输入上行速率 (默认50): " new_up_mbps
- new_up_mbps=${new_up_mbps:-50}
- if [[ $new_up_mbps =~ ^[0-9]+$ ]]; then
- echo "上行速率:$new_up_mbps Mbps"
- break
- else
- echo -e "${RED}错误:请输入数字作为上行速率!${NC}"
- fi
- done
- up_mbps="$new_up_mbps"
- }
- function set_down_speed() {
- while true; do
- read -p "请输入下行速率 (默认100): " new_down_mbps
- new_down_mbps=${new_down_mbps:-100}
- if [[ $new_down_mbps =~ ^[0-9]+$ ]]; then
- echo "下行速率:$new_down_mbps Mbps"
- break
- else
- echo -e "${RED}错误:请输入数字作为下行速率!${NC}"
- fi
- done
- down_mbps="$new_down_mbps"
- }
- function set_uuid() {
- while true; do
- read -p "请输入UUID(默认随机生成): " new_user_uuid
- if [ -z "$new_user_uuid" ]; then
- new_user_uuid=$(sing-box generate uuid 2>/dev/null || openssl rand -hex 16 | awk '{print substr($1,1,8) "-" substr($1,9,4) "-" substr($1,13,4) "-" substr($1,17,4) "-" substr($1,21)}')
- fi
- if [[ $new_user_uuid =~ ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ ]]; then
- echo "UUID:$new_user_uuid"
- break
- else
- echo -e "${RED}无效的UUID格式,请重新输入!${NC}"
- fi
- done
- user_uuids+=("$new_user_uuid")
- }
- function set_override_port() {
- while true; do
- read -p "请输入目标端口 (默认443): " new_override_port
- new_override_port=${new_override_port:-443}
- if [[ $new_override_port =~ ^[1-9][0-9]{0,4}$ && $new_override_port -le 65535 ]]; then
- echo "目标端口: $new_override_port"
- break
- else
- echo -e "${RED}错误:端口范围1-65535,请重新输入!${NC}"
- fi
- done
- override_port="$new_override_port"
- }
- function generate_unique_tag() {
- local config_file="/usr/local/etc/sing-box/config.json"
- while true; do
- random_tag=$(head /dev/urandom | tr -dc 'a-z0-9' | fold -w 8 | head -n 1)
- tag_label="${random_tag}-in"
- if ! grep -qE "\"tag\":\\s*\"$tag_label\"(,|$)" "$config_file"; then
- break
- fi
- done
- }
- function set_override_address() {
- while true; do
- read -p "请输入目标地址(IP或域名): " target_address
- if [[ -z "$target_address" ]]; then
- echo -e "${RED}错误:目标地址不能为空!${NC}"
- continue
- fi
- if ( [[ $target_address =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] && [[ $(grep -o '\.' <<< "$target_address" | wc -l) -eq 3 ]] ) || ( [[ $target_address =~ ^[a-fA-F0-9:]+$ ]] && [[ $(grep -o ':' <<< "$target_address" | wc -l) -ge 2 ]] ); then
- break
- else
- resolved_ips=$(host -t A "$target_address" | awk '/has address/ { print $4 }')
- if [[ -n "$resolved_ips" ]] && ( [[ "$resolved_ips" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || [[ "$resolved_ips" =~ ^[a-fA-F0-9:]+$ ]] ); then
- break
- else
- echo -e "${RED}错误:请输入有效的 IP 地址或域名!${NC}"
- fi
- fi
- done
- }
- function set_server_name() {
- while true; do
- read -p "请输入可用的 ServerName 列表 (默认为 nijigen-works.jp): " user_input
- if [[ -z "$user_input" ]]; then
- server_name="nijigen-works.jp"
- echo "ServerName:$server_name"
- break
- else
- server_name="$user_input"
- echo "ServerName:$server_name"
- echo "Verifying server's TLS version support..."
- if command -v openssl >/dev/null 2>&1; then
- local openssl_output=$(timeout 10s openssl s_client -connect "$server_name:443" -tls1_3 2>&1)
- if [[ $openssl_output == *"TLS_AES_256_GCM_SHA384"* || \
- $openssl_output == *"TLS_AES_128_GCM_SHA256"* || \
- $openssl_output == *"TLS_CHACHA20_POLY1305_SHA256"* || \
- $openssl_output == *"TLS_AES_128_CCM_SHA256"* || \
- $openssl_output == *"TLS_AES_128_CCM_8_SHA256"* ]]; then
- break
- else
- echo -e "${RED}该网址不支持 TLS 1.3,请重新输入!${NC}"
- fi
- else
- echo "OpenSSL is not installed, cannot verify TLS support."
- break
- fi
- fi
- done
- }
- function set_target_server() {
- while true; do
- read -p "请输入目标网站地址(默认为 nijigen-works.jp): " user_input
- if [[ -z "$user_input" ]]; then
- target_server="nijigen-works.jp"
- echo "目标网址:$target_server"
- break
- else
- target_server="$user_input"
- echo "目标网址:$target_server"
- echo "Verifying server's TLS version support..."
- if command -v openssl >/dev/null 2>&1; then
- local openssl_output=$(timeout 10s openssl s_client -connect "$target_server:443" -tls1_3 2>&1)
- if [[ $openssl_output == *"TLS_AES_256_GCM_SHA384"* || \
- $openssl_output == *"TLS_AES_128_GCM_SHA256"* || \
- $openssl_output == *"TLS_CHACHA20_POLY1305_SHA256"* || \
- $openssl_output == *"TLS_AES_128_CCM_SHA256"* || \
- $openssl_output == *"TLS_AES_128_CCM_8_SHA256"* ]]; then
- break
- else
- echo -e "${RED}该目标网站地址不支持 TLS 1.3,请重新输入!${NC}"
- fi
- else
- echo "OpenSSL is not installed, cannot verify TLS support."
- break
- fi
- fi
- done
- }
- function get_local_ip() {
- local local_ip_v4
- local local_ip_v6
- local_ip_v4=$(curl -s4 https://api.myip.com | grep -o '"ip":"[^"]*' | awk -F ':"' '{print $2}')
- if [[ -n "$local_ip_v4" ]]; then
- ip_v4="$local_ip_v4"
- else
- local_ip_v4=$(curl -s4 icanhazip.com)
- if [[ -n "$local_ip_v4" ]]; then
- ip_v4="$local_ip_v4"
- fi
- fi
- local_ip_v6=$(curl -s6 https://api.myip.com | grep -o '"ip":"[^"]*' | awk -F ':"' '{print $2}')
- if [[ -n "$local_ip_v6" ]]; then
- ip_v6="$local_ip_v6"
- else
- local_ip_v6=$(curl -s6 icanhazip.com)
- if [[ -n "$local_ip_v6" ]]; then
- ip_v6="$local_ip_v6"
- fi
- fi
- if [[ -z "$ip_v4" && -z "$ip_v6" ]]; then
- echo -e "${RED}无法获取本机IP地址!${NC}"
- fi
- }
- function get_ech_keys() {
- local input_file="/etc/ssl/private/ech.tmp"
- local output_file="/etc/ssl/private/ech.pem"
- sing-box generate ech-keypair [--pq-signature-schemes-enabled] > "$input_file"
- IFS=$'\n' read -d '' -ra lines < "$input_file"
- exec 3>"$output_file"
- in_ech_keys_section=false
- in_ech_configs_section=false
- for line in "${lines[@]}"; do
- if [[ "$line" == *"BEGIN ECH KEYS"* ]]; then
- in_ech_keys_section=true
- ech_key+=" \"$line\",\n"
- elif [[ "$line" == *"END ECH KEYS"* ]]; then
- in_ech_keys_section=false
- ech_key+=" \"$line\""
- elif [[ "$line" == *"BEGIN ECH CONFIGS"* ]]; then
- in_ech_configs_section=true
- ech_config+=" \"$line\",\n"
- elif [[ "$line" == *"END ECH CONFIGS"* ]]; then
- in_ech_configs_section=false
- ech_config+=" \"$line\""
- elif [ "$in_ech_keys_section" = true ]; then
- ech_key+=" \"$line\",\n"
- elif [ "$in_ech_configs_section" = true ]; then
- ech_config+=" \"$line\",\n"
- else
- echo "\"$line\"," >&3
- fi
- done
- exec 3>&-
- rm "$input_file"
- }
- function get_domain() {
- while true; do
- read -p "请输入域名(关闭Cloudflare代理): " user_domain
- resolved_ipv4=$(dig +short A "$user_domain" 2>/dev/null)
- resolved_ipv6=$(dig +short AAAA "$user_domain" 2>/dev/null)
- if [[ -z $user_domain ]]; then
- echo -e "${RED}错误:域名不能为空,请重新输入!${NC}"
- else
- if [[ ("$resolved_ipv4" == "$ip_v4" && ! -z "$resolved_ipv4") || ("$resolved_ipv6" == "$ip_v6" && ! -z "$resolved_ipv6") ]]; then
- break
- else
- if [[ -z "$resolved_ipv4" && -n "$ip_v4" ]]; then
- resolved_ip_v4=$(ping -4 "$user_domain" -c 1 2>/dev/null | sed '1{s/[^(]*(//;s/).*//;q}')
- if [[ ("$resolved_ip_v4" == "$ip_v4" && ! -z "$resolved_ip_v4") ]]; then
- break
- fi
- fi
- if [[ -z "$resolved_ipv6" && -n "$ip_v6" ]]; then
- resolved_ip_v6=$(ping -6 "$user_domain" -c 1 2>/dev/null | sed '1{s/[^(]*(//;s/).*//;q}')
- if [[ ("$resolved_ip_v6" == "$ip_v6" && ! -z "$resolved_ip_v6") ]]; then
- break
- fi
- fi
- echo -e "${RED}错误:域名未绑定本机IP,请重新输入!${NC}"
- fi
- fi
- done
- domain="$user_domain"
- }
- function verify_domain() {
- new_domain=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_id" \
- -H "Authorization: Bearer $api_token" | jq -r '.result.name')
- if [[ $new_domain =~ \.(tk|ml|ga|gq|cf)$ ]]; then
- echo -e "${RED}您的域名为$new_domain,该域名不支持使用 CloudFlare 的 API 申请证书,请选择其他方式申请证书!${NC}"
- domain_supported=false
- else
- while true; do
- read -p "请输入主域名前缀(若为空则使用主域名申请证书,不需要在 CloudFlare 添加 DNS 解析记录): " domain_prefix
- if [ -z "$domain_prefix" ]; then
- domain="$new_domain"
- record_name="$domain_prefix"
- break
- else
- domain="$domain_prefix"."$new_domain"
- record_name="$domain_prefix"
- break
- fi
- done
- domain_supported=true
- fi
- }
- function set_dns_record() {
- if [[ -z "$record_name" ]]; then
- name_value="@"
- else
- name_value="$record_name"
- fi
- if [[ -n "$ip_v4" ]]; then
- record_content=" $ip_v4"
- record_type="A"
- elif [[ -z "$ip_v4" && -n "$ip_v6" ]]; then
- record_content=" $ip_v6"
- record_type="AAAA"
- fi
- curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_Zone_ID/dns_records" \
- -H "Authorization: Bearer $CF_Token" \
- -H "Content-Type: application/json" \
- --data "{\"type\":\"$record_type\",\"name\":\"$name_value\",\"content\":\"$record_content\",\"ttl\":120,\"proxied\":false}" >/dev/null
- }
- function get_api_token() {
- while true; do
- read -p "请输入 CloudFlare 的限制性 API 令牌: " api_token
- if [[ ! $api_token =~ ^[A-Za-z0-9_-]{40}$ ]]; then
- echo -e "${RED}API令牌格式不正确,请重新输入!${NC}"
- else
- export CF_Token="$api_token"
- break
- fi
- done
- }
- function get_zone_id() {
- while true; do
- read -p "请输入 CloudFlare 的区域 ID: " zone_id
- if [[ ! $zone_id =~ ^[a-z0-9]{32}$ ]]; then
- echo -e "${RED}CloudFlare 的区域 ID 格式不正确,请重新输入!${NC}"
- else
- export CF_Zone_ID="$zone_id"
- break
- fi
- done
- }
- function get_api_email() {
- while true; do
- read -p "请输入 CloudFlare 的登录邮箱: " api_email
- if [[ ! $api_email =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$ ]]; then
- echo -e "${RED}邮箱格式不正确,请重新输入!${NC}"
- else
- export CF_Email="$api_email"
- break
- fi
- done
- }
-
- function set_fake_domain() {
- while true; do
- read -p "请输入伪装网址(默认: www.fan-2000.com): " fake_domain
- fake_domain=${fake_domain:-"www.fan-2000.com"}
- if curl --output /dev/null --silent --head --fail "$fake_domain"; then
- echo "伪装网址: $fake_domain"
- break
- else
- echo -e "${RED}伪装网址无效或不可用,请重新输入!${NC}"
- fi
- done
- }
- function set_certificate_path() {
- while true; do
- read -p "请输入 PEM 证书位置: " certificate_path_input
- if [[ ! -f "$certificate_path_input" ]]; then
- echo -e "${RED}错误:证书文件不存在,请重新输入!${NC}"
- continue
- fi
- certificate_file=$(basename "$certificate_path_input")
- allowed_extensions=("crt" "pem")
- if [[ ! "${allowed_extensions[@]}" =~ "${certificate_file##*.}" ]]; then
- echo -e "${RED}错误:不支持的证书格式,请配置.crt或.pem格式的证书文件!${NC}"
- continue
- fi
- certificate_path="$certificate_path_input"
- break
- done
- }
- function set_private_key_path() {
- while true; do
- read -p "请输入 PEM 私钥位置: " private_key_path_input
- if [[ ! -f "$private_key_path_input" ]]; then
- echo -e "${RED}错误:私钥文件不存在,请重新输入!${NC}"
- continue
- fi
- private_key_file=$(basename "$private_key_path_input")
- allowed_extensions=("key" "pem")
- if [[ ! "${allowed_extensions[@]}" =~ "${private_key_file##*.}" ]]; then
- echo -e "${RED}错误:不支持的私钥格式,请配置.key或.pem格式的私钥文件!${NC}"
- continue
- fi
- private_key_path="$private_key_path_input"
- break
- done
- }
- function apply_certificate() {
- certificate_path="/etc/ssl/private/"$domain".crt"
- private_key_path="/etc/ssl/private/"$domain".key"
- local has_ipv4=false
- local ca_servers=("letsencrypt" "zerossl")
- local return_to_menu=false
- if [[ -n "$ip_v4" ]]; then
- has_ipv4=true
- fi
- echo "Requesting a certificate..."
- curl -s https://get.acme.sh | sh -s email=example@gmail.com 2>&1 | tail -n 1
- alias acme.sh=~/.acme.sh/acme.sh
- for ca_server in "${ca_servers[@]}"; do
- echo "Requesting a certificate from $ca_server..."
- ~/.acme.sh/acme.sh --set-default-ca --server "$ca_server"
- if $has_ipv4; then
- result=$(~/.acme.sh/acme.sh --issue -d "$domain" --standalone -k ec-256 2>&1)
- else
- result=$(~/.acme.sh/acme.sh --issue -d "$domain" --standalone -k ec-256 --listen-v6 2>&1)
- fi
- if [[ $result == *"force"* ]]; then
- if $has_ipv4; then
- result=$(~/.acme.sh/acme.sh --issue -d "$domain" --standalone -k ec-256 --force 2>&1)
- else
- result=$(~/.acme.sh/acme.sh --issue -d "$domain" --standalone -k ec-256 --listen-v6 --force 2>&1)
- fi
- fi
- if [[ $result == *"log"* || $result == *"debug"* || $result == *"error"* ]]; then
- echo -e "${RED}$result ${NC}"
- continue
- fi
- if [[ $? -eq 0 ]]; then
- echo "Installing the certificate..."
- ~/.acme.sh/acme.sh --install-cert -d "$domain" --ecc --key-file "$private_key_path" --fullchain-file "$certificate_path"
- break
- else
- echo -e "${RED}Failed to obtain a certificate from $ca_server!${NC}"
- return_to_menu=true
- fi
- done
- if [ "$return_to_menu" = true ]; then
- echo -e "${RED}证书申请失败,请使用其它方法申请证书!${NC}"
- return 1
- fi
- }
- function Apply_api_certificate() {
- certificate_path="/etc/ssl/private/"$domain".crt"
- private_key_path="/etc/ssl/private/"$domain".key"
- local has_ipv4=false
- local ca_servers=("letsencrypt" "zerossl")
- if [[ -n "$ip_v4" ]]; then
- has_ipv4=true
- fi
- echo "Requesting a certificate..."
- curl -s https://get.acme.sh | sh -s email=example@gmail.com 2>&1 | tail -n 1
- alias acme.sh=~/.acme.sh/acme.sh
- for ca_server in "${ca_servers[@]}"; do
- echo "Requesting a certificate from $ca_server..."
- ~/.acme.sh/acme.sh --set-default-ca --server "$ca_server"
- if $has_ipv4; then
- result=$(~/.acme.sh/acme.sh --issue --dns dns_cf -d "$domain" -k ec-256 2>&1)
- else
- result=$(~/.acme.sh/acme.sh --issue --dns dns_cf -d "$domain" -k ec-256 --listen-v6 2>&1)
- fi
- if [[ $result == *"log"* || $result == *"debug"* || $result == *"error"* || $result == *"force"* ]]; then
- echo -e "${RED}$result ${NC}"
- return_to_menu=true
- continue
- fi
- if [[ $? -eq 0 ]]; then
- echo "Installing the certificate..."
- ~/.acme.sh/acme.sh --install-cert -d "$domain" --ecc --key-file "$private_key_path" --fullchain-file "$certificate_path"
- break
- else
- echo -e "${RED}Failed to obtain a certificate from $ca_server!${NC}"
- return_to_menu=true
- fi
- done
- if [ "$return_to_menu" = true ]; then
- echo -e "${RED}证书申请失败,请使用其它方法申请证书!${NC}"
- return 1
- fi
- }
- function Reapply_certificates() {
- local tls_info_file="/usr/local/etc/sing-box/tls_info.json"
- local has_ipv4=false
- if [ -n "$ip_v4" ]; then
- has_ipv4=true
- fi
- if ! command -v acme.sh &>/dev/null; then
- curl -s https://get.acme.sh | sh -s email=example@gmail.com
- fi
- alias acme.sh=~/.acme.sh/acme.sh
- echo "Setting CA server to Let's Encrypt..."
- ~/.acme.sh/acme.sh --set-default-ca --server "letsencrypt"
- jq -c '.[]' "$tls_info_file" | while read -r tls_info; do
- server_name=$(echo "$tls_info" | jq -r '.server_name')
- key_path=$(echo "$tls_info" | jq -r '.key_path')
- certificate_path=$(echo "$tls_info" | jq -r '.certificate_path')
- echo "Requesting certificate for $server_name..."
- result=$(
- if $has_ipv4; then
- ~/.acme.sh/acme.sh --issue --dns dns_cf -d "$server_name" -k ec-256 --force
- else
- ~/.acme.sh/acme.sh --issue --dns dns_cf -d "$server_name" -k ec-256 --listen-v6 --force
- fi
- )
- if [[ "$result" =~ "Cert success." ]]; then
- echo "Certificate for $server_name has been applied using Cloudflare DNS verification."
- else
- echo "Cloudflare DNS verification failed for $server_name. Trying standalone verification..."
- result=$(
- if $has_ipv4; then
- ~/.acme.sh/acme.sh --issue -d "$server_name" --standalone --force
- else
- ~/.acme.sh/acme.sh --issue -d "$server_name" --standalone --listen-v6 --force
- fi
- )
- if [[ "$result" =~ "BEGIN CERTIFICATE" && "$result" =~ "END CERTIFICATE" ]]; then
- echo "Certificate for $server_name has been applied using Let's Encrypt CA."
- else
- echo "Failed to obtain certificate for $server_name using standalone verification as well."
- return 1
- fi
- fi
- ~/.acme.sh/acme.sh --install-cert -d "$server_name" --ecc --key-file "$key_path" --fullchain-file "$certificate_path"
- echo "Certificate for $server_name has been installed."
- done
- rm -f "$tls_info_file"
- }
- function generate_private_key() {
- while true; do
- read -p "请输入私钥 (默认随机生成私钥): " local_private_key
- if [[ -z "$local_private_key" ]]; then
- local keypair_output=$(sing-box generate reality-keypair)
- local_private_key=$(echo "$keypair_output" | awk -F: '/PrivateKey/{gsub(/ /, "", $2); print $2}')
- local_public_key=$(echo "$keypair_output" | awk -F: '/PublicKey/{gsub(/ /, "", $2); print $2}')
- echo "private_key:$local_private_key"
- echo "public_key:$local_public_key"
- break
- else
- if [[ "$local_private_key" =~ ^[A-Za-z0-9_\-]{43}$ ]]; then
- read -p "请输入公钥: " local_public_key
- if ! [[ "$local_public_key" =~ ^[A-Za-z0-9_\-]{43}$ ]]; then
- echo -e "${RED}无效的公钥,请重新输入!${NC}"
- else
- break
- fi
- else
- echo -e "${RED}无效的私钥,请重新输入!${NC}"
- fi
- fi
- done
- public_key="$local_public_key"
- private_key="$local_private_key"
- }
- function create_self_signed_cert() {
- while true; do
- read -p "请输入要用于自签名证书的域名(默认为 bing.com): " user_domain
- domain_name=${user_domain:-"bing.com"}
- if curl --output /dev/null --silent --head --fail "$domain_name"; then
- openssl req -x509 -nodes -newkey ec:<(openssl ecparam -name prime256v1) -keyout /etc/ssl/private/$domain_name.key -out /etc/ssl/private/$domain_name.crt -subj "/CN=$domain_name" -days 36500
- chmod 777 /etc/ssl/private/$domain_name.key
- chmod 777 /etc/ssl/private/$domain_name.crt
- break
- else
- echo -e "${RED}无效的域名或域名不可用,请输入有效的域名!${NC}"
- fi
- done
- certificate_path="/etc/ssl/private/$domain_name.crt"
- private_key_path="/etc/ssl/private/$domain_name.key"
- }
- function select_encryption_method() {
- while true; do
- read -p "请选择加密方式(默认1):
- 1). 2022-blake3-chacha20-poly1305
- 2). 2022-blake3-aes-256-gcm
- 3). 2022-blake3-aes-128-gcm
- 4). xchacha20-ietf-poly1305
- 5). chacha20-ietf-poly1305
- 6). aes-256-gcm
- 7). aes-192-gcm
- 8). aes-128-gcm
- 请选择[1-8]: " encryption_choice
- encryption_choice=${encryption_choice:-1}
- case $encryption_choice in
- 1)
- ss_method="2022-blake3-chacha20-poly1305"
- ss_password=$(sing-box generate rand --base64 32)
- shadowtls_password=$(sing-box generate rand --base64 32)
- break
- ;;
- 2)
- ss_method="2022-blake3-aes-256-gcm"
- ss_password=$(sing-box generate rand --base64 32)
- shadowtls_password=$(sing-box generate rand --base64 32)
- break
- ;;
- 3)
- ss_method="2022-blake3-aes-128-gcm"
- ss_password=$(sing-box generate rand --base64 16)
- shadowtls_password=$(sing-box generate rand --base64 16)
- break
- ;;
- 4)
- ss_method="xchacha20-ietf-poly1305"
- ss_password=$(sing-box generate rand --base64 16)
- shadowtls_password=$(sing-box generate rand --base64 16)
- break
- ;;
- 5)
- ss_method="chacha20-ietf-poly1305"
- ss_password=$(sing-box generate rand --base64 16)
- shadowtls_password=$(sing-box generate rand --base64 16)
- break
- ;;
- 6)
- ss_method="aes-256-gcm"
- ss_password=$(sing-box generate rand --base64 16)
- shadowtls_password=$(sing-box generate rand --base64 16)
- break
- ;;
- 7)
- ss_method="aes-192-gcm"
- ss_password=$(sing-box generate rand --base64 16)
- shadowtls_password=$(sing-box generate rand --base64 16)
- break
- ;;
- 8)
- ss_method="aes-128-gcm"
- ss_password=$(sing-box generate rand --base64 16)
- shadowtls_password=$(sing-box generate rand --base64 16)
- break
- ;;
- *)
- echo -e "${RED}错误:无效的选择,请重新输入!${NC}"
- ;;
- esac
- done
- }
- function select_unlocked_items() {
- while true; do
- read -p "请选择要解锁的项目(支持多选):
- 1). ChatGPT
- 2). Netflix
- 3). Disney+
- 4). YouTube
- 请选择[1-4]: " choices
- if [[ "$choices" =~ ^[1234]+$ ]]; then
- selected=($(echo "$choices" | sed 's/./& /g'))
- break
- else
- echo -e "${RED}错误:无效的选择,请重新输入!${NC}"
- fi
- done
- }
- function update_geosite_array() {
- for choice in "${selected[@]}"; do
- case $choice in
- 1)
- geosite+=("\"openai\"")
- ;;
- 2)
- geosite+=("\"netflix\"")
- ;;
- 3)
- geosite+=("\"disney\"")
- ;;
- 4)
- geosite+=("\"youtube\"")
- ;;
- *)
- echo -e "${RED}无效的选择: $choice${NC}"
- ;;
- esac
- done
- }
- function select_outbound() {
- while true; do
- read -p "请选择出站网络 (默认1)
- 1). warp-IPv4
- 2). warp-IPv6
- 请选择[1-2]: " outbound_choice
- case $outbound_choice in
- 1|"")
- outbound="warp-IPv4-out"
- break
- ;;
- 2)
- outbound="warp-IPv6-out"
- break
- ;;
- *)
- echo -e "${RED}错误:无效的选项,请重新输入!${NC}"
- ;;
- esac
- done
- }
- function select_congestion_control() {
- local default_congestion_control="bbr"
- while true; do
- read -p "请选择拥塞控制算法 (默认$default_congestion_control):
- 1). bbr
- 2). cubic
- 3). new_reno
- 请选择[1-3]: " congestion_control
- case $congestion_control in
- 1)
- congestion_control="bbr"
- break
- ;;
- 2)
- congestion_control="cubic"
- break
- ;;
- 3)
- congestion_control="new_reno"
- break
- ;;
- "")
- congestion_control=$default_congestion_control
- break
- ;;
- *)
- echo -e "${RED}错误:无效的选择,请重新输入!${NC}"
- ;;
- esac
- done
- }
- function select_certificate_option() {
- local certificate_option
- local domain_supported=false
- local return_to_menu=false
- while true; do
- read -p "请选择证书来源 (默认1):
- 1). 自签证书
- 2). 监听80端口申请证书(standalone模式)
- 3). cloudflare API 申请证书(DNS API模式)
- 4). 自定义证书路径
- 请选择[1-4]: " certificate_option
- certificate_option=${certificate_option:-1}
- case $certificate_option in
- 1)
- if $disable_option; then
- echo -e "${RED}NaiveProxy节点不支持自签证书,请使用acme申请证书!${NC}"
- continue
- fi
- check_firewall_configuration
- create_self_signed_cert
- break
- ;;
- 2)
- get_local_ip
- get_domain
- check_firewall_configuration
- apply_certificate
- if [ "$return_to_menu" == true ]; then
- return_to_menu=false
- continue
- fi
- break
- ;;
- 3)
- get_local_ip
- get_api_token
- get_zone_id
- get_api_email
- verify_domain
- set_dns_record
- check_firewall_configuration
- if [ "$domain_supported" == "false" ]; then
- continue
- else
- Apply_api_certificate
- if [ "$return_to_menu" == true ]; then
- return_to_menu=false
- continue
- fi
- break
- fi
- ;;
- 4)
- get_local_ip
- get_domain
- check_firewall_configuration
- set_certificate_path
- set_private_key_path
- break
- ;;
- *)
- echo -e "${RED}错误:无效的选择,请重新输入!${NC}"
- ;;
- esac
- done
- }
- function select_vmess_type() {
- while true; do
- read -p "请选择节点类型(默认1):
- 1). VMess+TCP
- 2). VMess+WebSocket
- 3). VMess+gRPC
- 4). VMess+HTTPUpgrade
- 5). VMess+TCP+TLS
- 6). VMess+WebSocket+TLS
- 7). VMess+H2C+TLS
- 8). VMess+gRPC+TLS
- 9). VMess+HTTPUpgrade+TLS
- 请选择 [1-9]: " node_type
- case $node_type in
- "" | 1)
- tls_enabled=false
- break
- ;;
- 2)
- transport_ws=true
- tls_enabled=false
- break
- ;;
- 3)
- transport_grpc=true
- tls_enabled=false
- break
- ;;
- 4)
- transport_httpupgrade=true
- tls_enabled=false
- break
- ;;
- 5)
- tls_enabled=true
- break
- ;;
- 6)
- transport_ws=true
- tls_enabled=true
- break
- ;;
- 7)
- transport_http=true
- tls_enabled=true
- break
- ;;
- 8)
- transport_grpc=true
- tls_enabled=true
- break
- ;;
- 9)
- transport_httpupgrade=true
- tls_enabled=true
- break
- ;;
- *)
- echo -e "${RED}无效的选择,请重新输入!${NC}"
- ;;
- esac
- done
- }
- function select_vless_type() {
- while true; do
- read -p "请选择节点类型 (默认1):
- 1). VLESS+TCP
- 2). VLESS+WebSocket
- 3). VLESS+gRPC
- 4). VLESS+HTTPUpgrade
- 5). VLESS+Vision+REALITY
- 6). VLESS+H2C+REALITY
- 7). VLESS+gRPC+REALITY
- 请选择[1-7]: " flow_option
- case $flow_option in
- "" | 1)
- flow_type=""
- break
- ;;
- 2)
- flow_type=""
- transport_ws=true
- break
- ;;
- 3)
- flow_type=""
- transport_grpc=true
- break
- ;;
- 4)
- flow_type=""
- transport_httpupgrade=true
- break
- ;;
- 5)
- flow_type="xtls-rprx-vision"
- reality_enabled=true
- break
- ;;
- 6)
- flow_type=""
- transport_http=true
- reality_enabled=true
- break
- ;;
- 7)
- flow_type=""
- transport_grpc=true
- reality_enabled=true
- break
- ;;
- *)
- echo -e "${RED}错误的选项,请重新输入!${NC}" >&2
- ;;
- esac
- done
- }
- function select_trojan_type() {
- while true; do
- read -p "请选择节点类型(默认1):
- 1). Trojan+TCP
- 2). Trojan+WebSocket
- 3). Trojan+gRPC
- 4). Trojan+HTTPUpgrade
- 5). Trojan+TCP+TLS
- 6). Trojan+WebSocket+TLS
- 7). Trojan+H2C+TLS
- 8). Trojan+gRPC+TLS
- 9). Trojan+HTTPUpgrade+TLS
- 请选择 [1-9]: " setup_type
- case $setup_type in
- "" | 1)
- tls_enabled=false
- break
- ;;
- 2)
- transport_ws=true
- tls_enabled=false
- break
- ;;
- 3)
- transport_grpc=true
- tls_enabled=false
- break
- ;;
- 4)
- transport_httpupgrade=true
- tls_enabled=false
- break
- ;;
- 5)
- tls_enabled=true
- break
- ;;
- 6)
- transport_ws=true
- tls_enabled=true
- break
- ;;
- 7)
- transport_http=true
- tls_enabled=true
- break
- ;;
- 8)
- transport_grpc=true
- tls_enabled=true
- break
- ;;
- 9)
- transport_httpupgrade=true
- tls_enabled=true
- break
- ;;
- *)
- echo -e "${RED}无效的选择,请重新输入!${NC}"
- ;;
- esac
- done
- }
- function set_short_id() {
- while true; do
- read -p "请输入 Short_Id (用于区分不同的客户端,默认随机生成): " short_id
- if [[ -z "$short_id" ]]; then
- short_id=$(openssl rand -hex 8)
- echo "Short_Id:$short_id"
- break
- elif [[ "$short_id" =~ ^[0-9a-fA-F]{2,16}$ ]]; then
- echo "Short_Id:$short_id"
- break
- else
- echo "错误:请输入两到八位的十六进制字符串!"
- fi
- done
- short_ids+=("$short_id")
- }
- function set_short_ids() {
- while true; do
- set_short_id
- for ((i=0; i<${#short_ids[@]}; i++)); do
- short_id="${short_ids[$i]}"
- done
- read -p "是否继续添加 short id?(Y/N,默认N): " -e choice
- if [[ -z "$choice" ]]; then
- choice="N"
- fi
- if [[ "$choice" == "N" || "$choice" == "n" ]]; then
- short_Ids+="\n \"$short_id\""
- break
- elif [[ "$choice" == "Y" || "$choice" == "y" ]]; then
- short_Ids+="\n \"$short_id\","
- continue
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function tuic_multiple_users() {
- while true; do
- set_user_name
- set_user_password
- set_uuid
- for ((i=0; i<${#user_names[@]}; i++)); do
- user_name="${user_names[$i]}"
- user_uuid="${user_uuids[$i]}"
- user_password="${user_passwords[$i]}"
- done
- read -p "是否继续添加用户?(Y/N,默认N): " -e add_multiple_users
- if [[ -z "$add_multiple_users" ]]; then
- add_multiple_users="N"
- fi
- if [[ "$add_multiple_users" == "N" || "$add_multiple_users" == "n" ]]; then
- users+="\n {\n \"name\": \"$user_name\",\n \"uuid\": \"$user_uuid\",\n \"password\": \"$user_password\"\n }"
- break
- elif [[ "$add_multiple_users" == "Y" || "$add_multiple_users" == "y" ]]; then
- users+="\n {\n \"name\": \"$user_name\",\n \"uuid\": \"$user_uuid\",\n \"password\": \"$user_password\"\n },"
- continue
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function vmess_multiple_users() {
- while true; do
- set_uuid
- for ((i=0; i<${#user_uuids[@]}; i++)); do
- user_uuid="${user_uuids[$i]}"
- done
- read -p "是否继续添加用户?(Y/N,默认N): " -e add_multiple_users
- if [[ -z "$add_multiple_users" ]]; then
- add_multiple_users="N"
- fi
- if [[ "$add_multiple_users" == "N" || "$add_multiple_users" == "n" ]]; then
- users+="\n {\n \"uuid\": \"$user_uuid\",\n \"alterId\": 0\n }"
- break
- elif [[ "$add_multiple_users" == "Y" || "$add_multiple_users" == "y" ]]; then
- users+="\n {\n \"uuid\": \"$user_uuid\",\n \"alterId\": 0\n },"
- continue
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function vless_multiple_users() {
- while true; do
- set_uuid
- for ((i=0; i<${#user_uuids[@]}; i++)); do
- user_uuid="${user_uuids[$i]}"
- done
- read -p "是否继续添加用户?(Y/N,默认N): " -e add_multiple_users
- if [[ -z "$add_multiple_users" ]]; then
- add_multiple_users="N"
- fi
- if [[ "$add_multiple_users" == "N" || "$add_multiple_users" == "n" ]]; then
- users+="\n {\n \"uuid\": \"$user_uuid\",\n \"flow\": \"$flow_type\"\n }"
- break
- elif [[ "$add_multiple_users" == "Y" || "$add_multiple_users" == "y" ]]; then
- users+="\n {\n \"uuid\": \"$user_uuid\",\n \"flow\": \"$flow_type\"\n },"
- continue
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function socks_naive_multiple_users() {
- while true; do
- set_user_name
- set_user_password
- for ((i=0; i<${#user_names[@]}; i++)); do
- user_name="${user_names[$i]}"
- user_password="${user_passwords[$i]}"
- done
- read -p "是否继续添加用户?(Y/N,默认N): " -e add_multiple_users
- if [[ -z "$add_multiple_users" ]]; then
- add_multiple_users="N"
- fi
- if [[ "$add_multiple_users" == "N" || "$add_multiple_users" == "n" ]]; then
- users+="\n {\n \"username\": \"$user_name\",\n \"password\": \"$user_password\"\n }"
- break
- elif [[ "$add_multiple_users" == "Y" || "$add_multiple_users" == "y" ]]; then
- users+="\n {\n \"username\": \"$user_name\",\n \"password\": \"$user_password\"\n },"
- continue
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function hysteria_multiple_users() {
- while true; do
- set_user_name
- set_user_password
- for ((i=0; i<${#user_names[@]}; i++)); do
- user_name="${user_names[$i]}"
- user_password="${user_passwords[$i]}"
- done
- read -p "是否继续添加用户?(Y/N,默认N): " -e add_multiple_users
- if [[ -z "$add_multiple_users" ]]; then
- add_multiple_users="N"
- fi
- if [[ "$add_multiple_users" == "N" || "$add_multiple_users" == "n" ]]; then
- users+="\n {\n \"name\": \"$user_name\",\n \"auth_str\": \"$user_password\"\n }"
- break
- elif [[ "$add_multiple_users" == "Y" || "$add_multiple_users" == "y" ]]; then
- users+="\n {\n \"name\": \"$user_name\",\n \"auth_str\": \"$user_password\"\n },"
- continue
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function hy2_multiple_users() {
- while true; do
- set_user_name
- set_user_password
- for ((i=0; i<${#user_names[@]}; i++)); do
- user_name="${user_names[$i]}"
- user_password="${user_passwords[$i]}"
- done
- read -p "是否继续添加用户?(Y/N,默认N): " -e add_multiple_users
- if [[ -z "$add_multiple_users" ]]; then
- add_multiple_users="N"
- fi
- if [[ "$add_multiple_users" == "N" || "$add_multiple_users" == "n" ]]; then
- users+="\n {\n \"name\": \"$user_name\",\n \"password\": \"$user_password\"\n }"
- break
- elif [[ "$add_multiple_users" == "Y" || "$add_multiple_users" == "y" ]]; then
- users+="\n {\n \"name\": \"$user_name\",\n \"password\": \"$user_password\"\n },"
- continue
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function trojan_multiple_users() {
- while true; do
- set_user_password
- for ((i=0; i<${#user_passwords[@]}; i++)); do
- user_password="${user_passwords[$i]}"
- done
- read -p "是否继续添加用户?(Y/N,默认N): " -e add_multiple_users
- if [[ -z "$add_multiple_users" ]]; then
- add_multiple_users="N"
- fi
- if [[ "$add_multiple_users" == "N" || "$add_multiple_users" == "n" ]]; then
- users+="\n {\n \"password\": \"$user_password\"\n }"
- break
- elif [[ "$add_multiple_users" == "Y" || "$add_multiple_users" == "y" ]]; then
- users+="\n {\n \"password\": \"$user_password\"\n },"
- continue
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function shadowtls_multiple_users() {
- while true; do
- set_user_name
- set_stls_password
- for ((i=0; i<${#user_names[@]}; i++)); do
- user_name="${user_names[$i]}"
- stls_password="${stls_passwords[$i]}"
- done
- read -p "是否继续添加用户?(Y/N,默认N): " -e add_multiple_users
- if [[ -z "$add_multiple_users" ]]; then
- add_multiple_users="N"
- fi
- if [[ "$add_multiple_users" == "N" || "$add_multiple_users" == "n" ]]; then
- users+="\n {\n \"name\": \"$user_name\",\n \"password\": \"$stls_password\"\n }"
- break
- elif [[ "$add_multiple_users" == "Y" || "$add_multiple_users" == "y" ]]; then
- users+="\n {\n \"name\": \"$user_name\",\n \"password\": \"$stls_password\"\n },"
- continue
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function generate_transport_config() {
- if [[ "$transport_ws" = true ]]; then
- read -p "请输入 ws 路径 (默认随机生成): " transport_path_input
- transport_path=${transport_path_input:-/$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8)}
- if [[ ! "$transport_path" =~ ^/ ]]; then
- transport_path="/$transport_path"
- fi
- transport_config="\n \"transport\": {\n \"type\": \"ws\",\n \"path\": \"$transport_path\",\n \"max_early_data\": 2048,\n \"early_data_header_name\": \"Sec-WebSocket-Protocol\"\n },"
- elif [[ "$transport_httpupgrade" = true ]]; then
- transport_path=${transport_path_input:-/$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8)}
- if [[ ! "$transport_path" =~ ^/ ]]; then
- transport_path="/$transport_path"
- fi
- transport_config="\n \"transport\": {\n \"type\": \"httpupgrade\",\n \"path\": \"$transport_path\"\n },"
- elif [[ "$transport_grpc" = true ]]; then
- service_name=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 8)
- transport_config="\n \"transport\": {\n \"type\": \"grpc\",\n \"service_name\": \"$service_name\"\n },"
- elif [[ "$transport_http" = true ]]; then
- transport_config="\n \"transport\": {\n \"type\": \"http\"\n },"
- else
- transport_config=""
- fi
- }
- function generate_tls_config() {
- if [[ "$tls_enabled" = true ]]; then
- set_ech_config
- select_certificate_option
- fi
- if [ -z "$domain_name" ]; then
- if [ -n "$domain" ]; then
- server_name="$domain"
- fi
- else
- server_name="$domain_name"
- fi
-
- if [[ "$tls_enabled" = true ]]; then
- tls_config=",\n \"tls\": {\n \"enabled\": true,\n \"server_name\": \"$server_name\",\n \"certificate_path\": \"$certificate_path\",\n \"key_path\": \"$private_key_path\"$ech_server_config\n }"
- fi
- }
- function set_ech_config() {
- while true; do
- read -p "是否开启 ECH?(Y/N,默认Y):" enable_ech
- enable_ech="${enable_ech:-Y}"
- if [[ "$enable_ech" == "y" || "$enable_ech" == "Y" ]]; then
- get_ech_keys
- enable_ech=true
- ech_server_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"key\": [\n$ech_key\n ]\n }"
- break
- elif [[ "$enable_ech" == "n" || "$enable_ech" == "N" ]]; then
- enable_ech=false
- ech_server_config=""
- break
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
-
- function generate_reality_config() {
- if [[ "$reality_enabled" = true ]]; then
- set_server_name
- set_target_server
- generate_private_key
- set_short_ids
- reality_config=",\n \"tls\": {\n \"enabled\": true,\n \"server_name\": \"$server_name\",\n \"reality\": {\n \"enabled\": true,\n \"handshake\": {\n \"server\": \"$target_server\",\n \"server_port\": 443\n },\n \"private_key\": \"$private_key\",\n \"short_id\": [$short_Ids\n ]\n }\n }"
- fi
- }
- function configure_quic_obfuscation() {
- while true; do
- read -p "是否开启QUIC流量混淆(如果你的网络屏蔽了 QUIC 或 HTTP/3 流量,请选择开启)?(Y/N,默认为N): " choice
- choice="${choice:-N}"
- if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
- read -p "请输入混淆密码(默认随机生成): " new_obfs_password
- if [[ -z "$new_obfs_password" ]]; then
- new_obfs_password=$(sing-box generate rand --base64 9 2>/dev/null || openssl rand -base64 9)
- fi
- obfs_config="\n \"obfs\": {\n \"type\": \"salamander\",\n \"password\": \"$new_obfs_password\"\n },"
- obfs_password="$new_obfs_password"
- echo "混淆密码:$obfs_password"
- break
- elif [[ "$choice" == "n" || "$choice" == "N" ]]; then
- obfs_config=""
- break
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function configure_obfuscation() {
- while true; do
- read -p "是否开启 obfs 混淆(用来绕过针对性的 DPI 屏蔽或者 QoS)?(Y/N,默认为N): " choice
- choice="${choice:-N}"
- if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
- read -p "请输入混淆密码(默认随机生成): " new_obfs_password
- if [[ -z "$new_obfs_password" ]]; then
- new_obfs_password=$(sing-box generate rand --base64 9 2>/dev/null || openssl rand -base64 9)
- fi
- obfs_config="\n \"obfs\": \"$new_obfs_password\","
- obfs_password="$new_obfs_password"
- echo "混淆密码:$obfs_password"
- break
- elif [[ "$choice" == "n" || "$choice" == "N" ]]; then
- obfs_config=""
- break
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function configure_multiplex() {
- while true; do
- read -p "是否开启多路复用?(Y/N,默认为Y): " choice
- choice="${choice:-Y}"
- if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
- configure_brutal
- multiplex_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"padding\": false$brutal_config\n }"
- break
- elif [[ "$choice" == "n" || "$choice" == "N" ]]; then
- multiplex_config=""
- break
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function configure_brutal() {
- while true; do
- read -p "是否开启 TCP Brutal?(Y/N,默认为N): " choice
- choice="${choice:-N}"
- if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
- set_up_speed
- set_down_speed
- brutal_config=",\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $up_mbps,\n \"down_mbps\": $down_mbps\n }"
- break
- elif [[ "$choice" == "n" || "$choice" == "N" ]]; then
- brutal_config=""
- break
- else
- echo -e "${RED}无效的输入,请重新输入!${NC}"
- fi
- done
- }
- function extract_tls_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tls_info_file="/usr/local/etc/sing-box/tls_info.json"
- jq '.inbounds[].tls | select(.server_name and .certificate_path and .key_path) | {server_name: .server_name, certificate_path: .certificate_path, key_path: .key_path}' "$config_file" | jq -s 'unique' > "$tls_info_file"
- }
- function validate_tls_info() {
- local tls_info_file="/usr/local/etc/sing-box/tls_info.json"
- local temp_tls_file="/usr/local/etc/sing-box/temp_tls_info.json"
- server_names=($(jq -r '.[].server_name' "$tls_info_file"))
- for server_name in "${server_names[@]}"; do
- local resolved_ipv4=$(dig +short A "$server_name" 2>/dev/null)
- local resolved_ipv6=$(dig +short AAAA "$server_name" 2>/dev/null)
- if [[ (-n "$resolved_ipv4" && "$resolved_ipv4" == "$ip_v4") || (-n "$resolved_ipv6" && "$resolved_ipv6" == "$ip_v6") ]]; then
- continue
- else
- jq 'map(select(.server_name != "'"$server_name"'"))' "$tls_info_file" > "$temp_tls_file"
- mv "$temp_tls_file" "$tls_info_file"
- fi
- done
- }
- function modify_route_rules() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local temp_config_file="/usr/local/etc/sing-box/temp_config.json"
- if jq -e '.route.rules[] | select(.geosite != null)' "$config_file" >/dev/null; then
- jq '(.route.rules |= [.[] | select(.geosite != null)] + [.[] | select(.geosite == null)])' "$config_file" > "$temp_config_file"
- mv "$temp_config_file" "$config_file"
- fi
- }
- function extract_variables_and_cleanup() {
- server=$(jq -r '.server' "$temp_file")
- server_port=$(jq -r '.server_port' "$temp_file")
- local_address_ipv4=$(jq -r '.local_address[0]' "$temp_file")
- local_address_ipv6=$(jq -r '.local_address[1]' "$temp_file")
- private_key=$(jq -r '.private_key' "$temp_file")
- peer_public_key=$(jq -r '.peer_public_key' "$temp_file")
- reserved=$(jq -c '.reserved' "$temp_file")
- mtu=$(jq -r '.mtu' "$temp_file")
- rm "$temp_file"
- }
- function log_outbound_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- if ! grep -q '"log": {' "$config_file" || ! grep -q '"route": {' "$config_file" || ! grep -q '"inbounds": \[' "$config_file" || ! grep -q '"outbounds": \[' "$config_file"; then
- echo -e '{\n "log": {\n },\n "route": {\n },\n "inbounds": [\n ],\n "outbounds": [\n ]\n}' > "$config_file"
- sed -i '/"log": {/!b;n;c\ "disabled": true,\n "level": "info",\n "timestamp": true\n },' "$config_file"
- sed -i '/"route": {/!b;n;c\ "rules": [\n ]\n },' "$config_file"
- sed -i '/"outbounds": \[/!b;n;c\ {\n "type": "direct",\n "tag": "direct"\n }\n ]' "$config_file"
- fi
- }
- function modify_format_inbounds_and_outbounds() {
- file_path="/usr/local/etc/sing-box/config.json"
- start_line_inbounds=$(grep -n '"inbounds": \[' "$file_path" | cut -d: -f1)
- start_line_outbounds=$(grep -n '"outbounds": \[' "$file_path" | cut -d: -f1)
- if [ -n "$start_line_inbounds" ]; then
- line_to_modify_inbounds=$((start_line_inbounds - 3))
- if [ "$line_to_modify_inbounds" -ge 1 ]; then
- sed -i "$line_to_modify_inbounds s/,//" "$file_path"
- fi
- fi
- if [ -n "$start_line_outbounds" ]; then
- line_to_modify_outbounds_1=$((start_line_outbounds - 2))
- line_to_modify_outbounds_2=$((start_line_outbounds - 1))
- if [ "$line_to_modify_outbounds_1" -ge 1 ]; then
- sed -i "$line_to_modify_outbounds_1 s/.*/ }/" "$file_path"
- sed -i "$line_to_modify_outbounds_2 s/.*/ ],/" "$file_path"
- fi
- fi
- }
- function generate_http_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local cert_path="$certificate_path"
- local key_path="$private_key_path"
- tls_enabled=true
- local tag_label
- generate_unique_tag
- set_listen_port
- socks_naive_multiple_users
- get_local_ip
- generate_tls_config
- local found_rules=0
- local found_inbounds=0
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v users="$users" -v tls_config="$tls_config" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"http\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true,"; print " \"set_system_proxy\": false,"; print " \"users\": [" users ""; print " ]" tls_config ""; print " },"; found_inbounds=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_Direct_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tag_label
- generate_unique_tag
- local found_rules=0
- local found_inbounds=0
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v target_address="$target_address" -v override_port="$override_port" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"direct\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true,"; print " \"sniff_timeout\": \"300ms\","; print " \"proxy_protocol\": false,"; print " \"override_address\": \"" target_address "\","; print " \"override_port\": " override_port; print " },"; found_inbounds=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_ss_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tag_label
- generate_unique_tag
- configure_multiplex
- local found_rules=0
- local found_inbounds=0
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v ss_method="$ss_method" -v ss_password="$ss_password" -v multiplex_config="$multiplex_config" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"shadowsocks\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true,"; print " \"method\": \"" ss_method "\","; print " \"password\": \"" ss_password "\"" multiplex_config ""; print " },"; found_inbounds=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_vmess_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local cert_path="$certificate_path"
- local key_path="$private_key_path"
- local tag_label
- generate_unique_tag
- select_vmess_type
- set_listen_port
- vmess_multiple_users
- generate_transport_config
- if [ "$transport_grpc" != true ] && [ "$transport_http" != true ]; then
- configure_multiplex
- fi
- get_local_ip
- generate_tls_config
- check_firewall_configuration
- local found_rules=0
- local found_inbounds=0
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v users="$users" -v transport_config="$transport_config" -v tls_config="$tls_config" -v multiplex_config="$multiplex_config" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"vmess\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true," transport_config ""; print " \"users\": [" users ""; print " ]" tls_config "" multiplex_config ""; print " },"; found=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_socks_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tag_label
- generate_unique_tag
- set_listen_port
- socks_naive_multiple_users
- local found_rules=0
- local found_inbounds=0
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v users="$users" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"socks\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true,"; print " \"users\": [" users ""; print " ]"; print " },"; found_inbounds=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_naive_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- disable_option=true
- local tag_label
- generate_unique_tag
- set_listen_port
- socks_naive_multiple_users
- get_local_ip
- select_certificate_option
- local cert_path="$certificate_path"
- local key_path="$private_key_path"
- local found_rules=0
- local found_inbounds=0
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v users="$users" -v domain="$domain" -v certificate_path="$certificate_path" -v private_key_path="$private_key_path" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"naive\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true,"; print " \"users\": [" users ""; print " ],"; print " \"tls\": {"; print " \"enabled\": true,"; print " \"server_name\": \"" domain "\","; print " \"certificate_path\": \"" certificate_path "\","; print " \"key_path\": \"" private_key_path "\""; print " }"; print " },"; found_inbounds=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_tuic_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tag_label
- generate_unique_tag
- set_listen_port
- tuic_multiple_users
- select_congestion_control
- get_local_ip
- set_ech_config
- select_certificate_option
- local cert_path="$certificate_path"
- local key_path="$private_key_path"
- local found_rules=0
- local found_inbounds=0
- local server_name="$domain"
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- fi
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v users="$users" -v congestion_control="$congestion_control" -v server_name="$server_name" -v certificate_path="$certificate_path" -v private_key_path="$private_key_path" -v ech_server_config="$ech_server_config" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"tuic\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true,"; print " \"users\": [" users ""; print " ],"; print " \"congestion_control\": \"" congestion_control "\","; print " \"auth_timeout\": \"3s\","; print " \"zero_rtt_handshake\": false,"; print " \"heartbeat\": \"10s\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"server_name\": \"" server_name "\","; print " \"alpn\": ["; print " \"h3\""; print " ],"; print " \"certificate_path\": \"" certificate_path "\","; print " \"key_path\": \"" private_key_path "\"" ech_server_config ""; print " }"; print " },"; found_inbounds=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_Hysteria_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tag_label
- generate_unique_tag
- set_listen_port
- set_up_speed
- set_down_speed
- hysteria_multiple_users
- configure_obfuscation
- get_local_ip
- set_ech_config
- select_certificate_option
- local cert_path="$certificate_path"
- local key_path="$private_key_path"
- local found_rules=0
- local found_inbounds=0
- local server_name="$domain"
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- fi
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v up_mbps="$up_mbps" -v down_mbps="$down_mbps" -v obfs_config="$obfs_config" -v users="$users" -v server_name="$server_name" -v certificate_path="$certificate_path" -v private_key_path="$private_key_path" -v ech_server_config="$ech_server_config" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"hysteria\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true,"; print " \"up_mbps\": " up_mbps ","; print " \"down_mbps\": " down_mbps ","obfs_config""; print " \"users\": [" users ""; print " ],"; print " \"tls\": {"; print " \"enabled\": true,"; print " \"server_name\": \"" server_name "\","; print " \"alpn\": ["; print " \"h3\""; print " ],"; print " \"certificate_path\": \"" certificate_path "\","; print " \"key_path\": \"" private_key_path "\"" ech_server_config ""; print " }"; print " },"; found_inbounds=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_shadowtls_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tag_label
- generate_unique_tag
- tag_label1="$tag_label"
- generate_unique_tag
- tag_label2="$tag_label"
- set_listen_port
- select_encryption_method
- shadowtls_multiple_users
- set_ss_password
- set_target_server
- configure_multiplex
- local found_rules=0
- local found_inbounds=0
- awk -v tag_label1="$tag_label1" -v tag_label2="$tag_label2" -v listen_port="$listen_port" -v users="$users" -v target_server="$target_server" -v ss_method="$ss_method" -v ss_password="$ss_password" -v multiplex_config="$multiplex_config" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label1 "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"shadowtls\","; print " \"tag\": \"" tag_label1 "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true,"; print " \"version\": 3,"; print " \"users\": [" users ""; print " ],"; print " \"handshake\": {"; print " \"server\": \"" target_server "\","; print " \"server_port\": 443"; print " },"; print " \"strict_mode\": true,"; print " \"detour\": \"" tag_label2 "\""; print " },"; print " {"; print " \"type\": \"shadowsocks\","; print " \"tag\": \"" tag_label2 "\","; print " \"listen\": \"127.0.0.1\","; print " \"method\": \"" ss_method "\","; print " \"password\": \"" ss_password "\"" multiplex_config ""; print " },"; found=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_juicity_config() {
- local config_file="/usr/local/etc/juicity/config.json"
- set_listen_port
- set_uuid
- set_user_password
- select_congestion_control
- get_local_ip
- select_certificate_option
- local cert_path="$certificate_path"
- local key_path="$private_key_path"
- awk -v listen_port="$listen_port" -v user_uuids="$user_uuids" -v user_passwords="$user_passwords" -v certificate_path="$certificate_path" -v private_key_path="$private_key_path" -v congestion_control="$congestion_control" 'BEGIN { print "{"; printf " \"listen\": \":%s\",\n", listen_port; printf " \"users\": {\n"; printf " \"%s\": \"%s\"\n", user_uuids, user_passwords; printf " },\n"; printf " \"certificate\": \"%s\",\n", certificate_path; printf " \"private_key\": \"%s\",\n", private_key_path; printf " \"congestion_control\": \"%s\",\n", congestion_control; printf " \"disable_outbound_udp443\": true,\n"; print " \"log_level\": \"info\""; print "}"}' > "$config_file"
- }
- function generate_vless_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tag_label
- generate_unique_tag
- select_vless_type
- set_listen_port
- vless_multiple_users
- generate_transport_config
- generate_reality_config
- if [[ "$flow_type" != xtls-rprx-vision ]] && [[ "$transport_grpc" != true ]] && [[ "$transport_http" != true ]]; then
- configure_multiplex
- fi
- local found_rules=0
- local found_inbounds=0
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v users="$users" -v transport_config="$transport_config" -v reality_config="$reality_config" -v multiplex_config="$multiplex_config" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"vless\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true," transport_config ""; print " \"users\": [" users ""; print " ]"reality_config"" multiplex_config ""; print " },"; found=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_Hy2_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tag_label
- generate_unique_tag
- set_listen_port
- set_up_speed
- set_down_speed
- hy2_multiple_users
- configure_quic_obfuscation
- set_fake_domain
- get_local_ip
- set_ech_config
- select_certificate_option
- local cert_path="$certificate_path"
- local key_path="$private_key_path"
- local found_rules=0
- local found_inbounds=0
- local server_name="$domain"
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- fi
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v up_mbps="$up_mbps" -v down_mbps="$down_mbps" -v obfs_config="$obfs_config" -v users="$users" -v fake_domain="$fake_domain" -v server_name="$server_name" -v certificate_path="$certificate_path" -v private_key_path="$private_key_path" -v ech_server_config="$ech_server_config" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"hysteria2\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true,"; print " \"up_mbps\": " up_mbps ","; print " \"down_mbps\": " down_mbps ","obfs_config""; print " \"users\": [" users ""; print " ],"; print " \"ignore_client_bandwidth\": false,"; print " \"masquerade\": \"https://" fake_domain "\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"server_name\": \"" server_name "\","; print " \"alpn\": ["; print " \"h3\""; print " ],"; print " \"certificate_path\": \"" certificate_path "\","; print " \"key_path\": \"" private_key_path "\"" ech_server_config ""; print " }"; print " },"; found=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
- function generate_trojan_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local tag_label
- generate_unique_tag
- select_trojan_type
- set_listen_port
- trojan_multiple_users
- generate_transport_config
- if [ "$transport_grpc" != true ] && [ "$transport_http" != true ]; then
- configure_multiplex
- fi
- get_local_ip
- generate_tls_config
- local cert_path="$certificate_path"
- local key_path="$private_key_path"
- check_firewall_configuration
- local found_rules=0
- local found_inbounds=0
- awk -v tag_label="$tag_label" -v listen_port="$listen_port" -v users="$users" -v transport_config="$transport_config" -v tls_config="$tls_config" -v multiplex_config="$multiplex_config" '
- /"rules": \[/{found_rules=1}
- /"inbounds": \[/{found_inbounds=1}
- {print}
- found_rules && /"rules": \[/{print " {"; print " \"inbound\": [\"" tag_label "\"],"; print " \"outbound\": \"direct\""; print " },"; found_rules=0}
- found_inbounds && /"inbounds": \[/{print " {"; print " \"type\": \"trojan\","; print " \"tag\": \"" tag_label "\","; print " \"listen\": \"::\","; print " \"listen_port\": " listen_port ","; print " \"sniff\": true,"; print " \"sniff_override_destination\": true," transport_config ""; print " \"users\": [" users ""; print " ]" tls_config "" multiplex_config ""; print " },"; found=0}
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- }
-
- function update_route_file() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local geosite_list=$(IFS=,; echo "${geosite[*]}")
- local geosite_formatted=$(sed 's/,/,\\n /g' <<< "$geosite_list")
- echo "正在配置 WireGuard..."
- sed -i '/"rules": \[/!b;a\
- {\
- "geosite": [\
- '"$geosite_formatted"'\
- ],\
- "outbound": "'"$1"'"\
- },' "$config_file"
- }
- function update_outbound_file() {
- local config_file="/usr/local/etc/sing-box/config.json"
- awk -v server="$server" -v server_port="$server_port" -v local_address_ipv4="$local_address_ipv4" -v local_address_ipv6="$local_address_ipv6" -v private_key="$private_key" -v peer_public_key="$peer_public_key" -v reserved="$reserved" -v mtu="$mtu" '
- {
- if ($0 ~ /"outbounds": \[/) {
- print $0
- for (i=1; i<=4; i++) {
- getline
- if (i == 4) {
- print "" $0 ","
- } else {
- print $0
- }
- }
- print " {"; print " \"type\": \"direct\","; print " \"tag\": \"warp-IPv4-out\","; print " \"detour\": \"wireguard-out\","; print " \"domain_strategy\": \"ipv4_only\""; print " },"; print " {"; print " \"type\": \"direct\","; print " \"tag\": \"warp-IPv6-out\","; print " \"detour\": \"wireguard-out\","; print " \"domain_strategy\": \"ipv6_only\""; print " },"; print " {"; print " \"type\": \"wireguard\","; print " \"tag\": \"wireguard-out\","; print " \"server\": \"" server "\","; print " \"server_port\": " server_port ","; print " \"system_interface\": false,"; print " \"interface_name\": \"wg0\","; print " \"local_address\": ["; print " \"" local_address_ipv4 "\","; print " \"" local_address_ipv6 "\"" ; print " ],"; print " \"private_key\": \"" private_key "\","; print " \"peer_public_key\": \"" peer_public_key "\","; print " \"reserved\": " reserved ","; print " \"mtu\": " mtu; print " }"
- } else {
- print $0
- }
- }
- ' "$config_file" > "$config_file.tmp"
- mv "$config_file.tmp" "$config_file"
- echo "WireGuard 配置完成。"
- }
- function write_phone_client_file() {
- local dir="/usr/local/etc/sing-box"
- local phone_client="${dir}/phone_client.json"
- if [ ! -s "${phone_client}" ]; then
- awk 'BEGIN { print "{"; print " \"log\": {"; print " \"disabled\": false,"; print " \"level\": \"warn\","; print " \"timestamp\": true"; print " },"; print " \"dns\": {"; print " \"servers\": ["; print " {"; print " \"tag\": \"dns_proxy\","; print " \"address\": \"https://dns.google/dns-query\","; print " \"address_resolver\": \"dns_local\","; print " \"detour\": \"select\""; print " },"; print " {"; print " \"tag\": \"dns_direct\","; print " \"address\": \"https://dns.alidns.com/dns-query\","; print " \"address_resolver\": \"dns_local\","; print " \"detour\": \"direct\""; print " },"; print " {"; print " \"tag\": \"dns_block\","; print " \"address\": \"rcode://success\""; print " },"; print " {"; print " \"tag\": \"dns_fakeip\","; print " \"address\": \"fakeip\""; print " },"; print " {"; print " \"tag\": \"dns_local\","; print " \"address\": \"223.5.5.5\","; print " \"detour\": \"direct\""; print " }"; print " ],"; print " \"rules\": ["; print " {"; print " \"outbound\": \"any\","; print " \"server\": \"dns_local\""; print " },"; print " {"; print " \"geosite\": ["; print " \"category-ads-all\""; print " ],"; print " \"server\": \"dns_block\","; print " \"disable_cache\": true"; print " },"; print " {"; print " \"query_type\": ["; print " \"A\","; print " \"AAAA\""; print " ],"; print " \"server\": \"dns_fakeip\""; print " },"; print " {"; print " \"clash_mode\": \"Direct\","; print " \"server\": \"dns_direct\""; print " },"; print " {"; print " \"clash_mode\": \"Global\","; print " \"server\": \"dns_proxy\""; print " },"; print " {"; print " \"type\": \"logical\","; print " \"mode\": \"and\","; print " \"rules\": ["; print " {"; print " \"geosite\": \"geolocation-!cn\","; print " \"invert\": true"; print " },"; print " {"; print " \"geosite\": ["; print " \"cn\","; print " \"category-companies@cn\""; print " ]"; print " }"; print " ],"; print " \"server\": \"dns_direct\""; print " }"; print " ],"; print " \"final\": \"dns_proxy\","; print " \"strategy\": \"ipv4_only\","; print " \"independent_cache\": true,"; print " \"fakeip\": {"; print " \"enabled\": true,"; print " \"inet4_range\": \"198.18.0.0/15\","; print " \"inet6_range\": \"fc00::/18\""; print " }"; print " },"; print " \"route\": {"; print " \"geoip\": {"; print " \"download_url\": \"https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db\","; print " \"download_detour\": \"select\""; print " },"; print " \"geosite\": {"; print " \"download_url\": \"https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db\","; print " \"download_detour\": \"select\""; print " },"; print " \"rules\": ["; print " {"; print " \"protocol\": \"dns\","; print " \"outbound\": \"dns-out\""; print " },"; print " {"; print " \"geoip\": \"private\","; print " \"outbound\": \"direct\""; print " },"; print " {"; print " \"clash_mode\": \"Direct\","; print " \"outbound\": \"direct\""; print " },"; print " {"; print " \"clash_mode\": \"Global\","; print " \"outbound\": \"select\""; print " },"; print " {"; print " \"type\": \"logical\","; print " \"mode\": \"and\","; print " \"rules\": ["; print " {"; print " \"geosite\": \"geolocation-!cn\","; print " \"invert\": true"; print " },"; print " {"; print " \"geosite\": ["; print " \"cn\","; print " \"category-companies@cn\""; print " ],"; print " \"geoip\": \"cn\""; print " }"; print " ],"; print " \"outbound\": \"direct\""; print " }"; print " ],"; print " \"final\": \"select\","; print " \"auto_detect_interface\": true"; print " },"; print " \"inbounds\": ["; print " {"; print " \"type\": \"tun\","; print " \"tag\": \"tun-in\","; print " \"inet4_address\": \"172.19.0.1/30\","; print " \"inet6_address\": \"fdfe:dcba:9876::1/126\","; print " \"auto_route\": true,"; print " \"strict_route\": true,"; print " \"stack\": \"mixed\","; print " \"sniff\": true,"; print " \"sniff_override_destination\": false"; print " }"; print " ],"; print " \"outbounds\": ["; print " {"; print " \"type\": \"urltest\","; print " \"tag\": \"auto\","; print " \"outbounds\": ["; print " ],"; print " \"url\": \"https://www.gstatic.com/generate_204\","; print " \"interval\": \"1m\","; print " \"tolerance\": 50,"; print " \"interrupt_exist_connections\": false"; print " },"; print " {"; print " \"type\": \"selector\","; print " \"tag\": \"select\","; print " \"outbounds\": ["; print " \"auto\""; print " ],"; print " \"default\": \"auto\","; print " \"interrupt_exist_connections\": false"; print " },"; print " {"; print " \"type\": \"direct\","; print " \"tag\": \"direct\""; print " },"; print " {"; print " \"type\": \"block\","; print " \"tag\": \"block\""; print " },"; print " {"; print " \"type\": \"dns\","; print " \"tag\": \"dns-out\""; print " }"; print " ],"; print " \"experimental\": {"; print " \"clash_api\": {"; print " \"external_controller\": \"127.0.0.1:9090\","; print " \"external_ui\": \"ui\","; print " \"external_ui_download_detour\": \"direct\","; print " \"store_fakeip\": true"; print " }"; print " },"; print " \"ntp\": {"; print " \"enabled\": true,"; print " \"server\": \"time.apple.com\","; print " \"server_port\": 123,"; print " \"interval\": \"30m\","; print " \"detour\": \"direct\""; print " }"; print "}" }' > "${phone_client}"
- fi
- }
- function write_win_client_file() {
- local dir="/usr/local/etc/sing-box"
- local win_client="${dir}/win_client.json"
- if [ ! -s "${win_client}" ]; then
- awk 'BEGIN { print "{"; print " \"log\": {"; print " \"disabled\": false,"; print " \"level\": \"warn\","; print " \"timestamp\": true"; print " },"; print " \"dns\": {"; print " \"servers\": ["; print " {"; print " \"tag\": \"dns_proxy\","; print " \"address\": \"https://dns.google/dns-query\","; print " \"address_resolver\": \"dns_local\","; print " \"detour\": \"select\""; print " },"; print " {"; print " \"tag\": \"dns_direct\","; print " \"address\": \"https://dns.alidns.com/dns-query\","; print " \"address_resolver\": \"dns_local\","; print " \"detour\": \"direct\""; print " },"; print " {"; print " \"tag\": \"dns_block\","; print " \"address\": \"rcode://success\""; print " },"; print " {"; print " \"tag\": \"dns_fakeip\","; print " \"address\": \"fakeip\""; print " },"; print " {"; print " \"tag\": \"dns_local\","; print " \"address\": \"223.5.5.5\","; print " \"detour\": \"direct\""; print " }"; print " ],"; print " \"rules\": ["; print " {"; print " \"outbound\": \"any\","; print " \"server\": \"dns_local\""; print " },"; print " {"; print " \"geosite\": ["; print " \"category-ads-all\""; print " ],"; print " \"server\": \"dns_block\","; print " \"disable_cache\": true"; print " },"; print " {"; print " \"query_type\": ["; print " \"A\","; print " \"AAAA\""; print " ],"; print " \"server\": \"dns_fakeip\""; print " },"; print " {"; print " \"clash_mode\": \"Direct\","; print " \"server\": \"dns_direct\""; print " },"; print " {"; print " \"clash_mode\": \"Global\","; print " \"server\": \"dns_proxy\""; print " },"; print " {"; print " \"type\": \"logical\","; print " \"mode\": \"and\","; print " \"rules\": ["; print " {"; print " \"geosite\": \"geolocation-!cn\","; print " \"invert\": true"; print " },"; print " {"; print " \"geosite\": ["; print " \"cn\","; print " \"category-companies@cn\""; print " ]"; print " }"; print " ],"; print " \"server\": \"dns_direct\""; print " }"; print " ],"; print " \"final\": \"dns_proxy\","; print " \"strategy\": \"ipv4_only\","; print " \"independent_cache\": true,"; print " \"fakeip\": {"; print " \"enabled\": true,"; print " \"inet4_range\": \"198.18.0.0/15\","; print " \"inet6_range\": \"fc00::/18\""; print " }"; print " },"; print " \"route\": {"; print " \"geoip\": {"; print " \"download_url\": \"https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db\","; print " \"download_detour\": \"select\""; print " },"; print " \"geosite\": {"; print " \"download_url\": \"https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db\","; print " \"download_detour\": \"select\""; print " },"; print " \"rules\": ["; print " {"; print " \"protocol\": \"dns\","; print " \"outbound\": \"dns-out\""; print " },"; print " {"; print " \"geoip\": \"private\","; print " \"outbound\": \"direct\""; print " },"; print " {"; print " \"clash_mode\": \"Direct\","; print " \"outbound\": \"direct\""; print " },"; print " {"; print " \"clash_mode\": \"Global\","; print " \"outbound\": \"select\""; print " },"; print " {"; print " \"type\": \"logical\","; print " \"mode\": \"and\","; print " \"rules\": ["; print " {"; print " \"geosite\": \"geolocation-!cn\","; print " \"invert\": true"; print " },"; print " {"; print " \"geosite\": ["; print " \"cn\","; print " \"category-companies@cn\""; print " ],"; print " \"geoip\": \"cn\""; print " }"; print " ],"; print " \"outbound\": \"direct\""; print " }"; print " ],"; print " \"final\": \"select\","; print " \"auto_detect_interface\": true"; print " },"; print " \"inbounds\": ["; print " {"; print " \"type\": \"mixed\","; print " \"tag\": \"mixed-in\","; print " \"listen\": \"::\","; print " \"listen_port\": 1080,"; print " \"sniff\": true,"; print " \"set_system_proxy\": false"; print " }"; print " ],"; print " \"outbounds\": ["; print " {"; print " \"type\": \"urltest\","; print " \"tag\": \"auto\","; print " \"outbounds\": ["; print " ],"; print " \"url\": \"https://www.gstatic.com/generate_204\","; print " \"interval\": \"1m\","; print " \"tolerance\": 50,"; print " \"interrupt_exist_connections\": false"; print " },"; print " {"; print " \"type\": \"selector\","; print " \"tag\": \"select\","; print " \"outbounds\": ["; print " \"auto\""; print " ],"; print " \"default\": \"auto\","; print " \"interrupt_exist_connections\": false"; print " },"; print " {"; print " \"type\": \"direct\","; print " \"tag\": \"direct\""; print " },"; print " {"; print " \"type\": \"block\","; print " \"tag\": \"block\""; print " },"; print " {"; print " \"type\": \"dns\","; print " \"tag\": \"dns-out\""; print " }"; print " ],"; print " \"experimental\": {"; print " \"clash_api\": {"; print " \"external_controller\": \"127.0.0.1:9090\","; print " \"external_ui\": \"ui\","; print " \"external_ui_download_detour\": \"direct\","; print " \"store_fakeip\": true"; print " }"; print " },"; print " \"ntp\": {"; print " \"enabled\": true,"; print " \"server\": \"time.apple.com\","; print " \"server_port\": 123,"; print " \"interval\": \"30m\","; print " \"detour\": \"direct\""; print " }"; print "}" }' > "${win_client}"
- fi
- }
- function write_clash_yaml() {
- local dir="/usr/local/etc/sing-box"
- local clash_yaml="${dir}/clash.yaml"
- if [ ! -s "${clash_yaml}" ]; then
- awk 'BEGIN { print "mixed-port: 10801"; print "allow-lan: true"; print "bind-address: \"*\""; print "find-process-mode: strict"; print "mode: rule"; print "geodata-mode: true"; print "geox-url:"; print " geoip: \"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat\""; print " geosite: \"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat\""; print " mmdb: \"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb\""; print "log-level: info"; print "ipv6: true"; print "global-client-fingerprint: chrome"; print "tun:"; print " enable: true"; print " stack: system"; print " dns-hijack:"; print " - 0.0.0.0:53"; print " auto-detect-interface: true"; print " auto-route: true"; print " mtu: 9000"; print "profile:"; print " store-selected: false"; print " store-fake-ip: true"; print "sniffer:"; print " enable: true"; print " override-destination: false"; print " sniff:"; print " TLS:"; print " ports: [443, 8443]"; print " HTTP:"; print " ports: [80, 8080-8880]"; print " override-destination: true"; print "dns:"; print " enable: true"; print " prefer-h3: true"; print " listen: 0.0.0.0:53"; print " ipv6: true"; print " ipv6-timeout: 300"; print " default-nameserver:"; print " - 223.5.5.5"; print " enhanced-mode: fake-ip"; print " fake-ip-range: 198.18.0.1/16"; print " nameserver:"; print " - https://doh.pub/dns-query"; print " - https://dns.alidns.com/dns-query"; print " fallback:"; print " - https://dns.google/dns-query"; print " - https://1.1.1.1/dns-query"; print " fallback-filter:"; print " geoip: true"; print " geoip-code: CN"; print " geosite:"; print " - gfw"; print " ipcidr:"; print " - 240.0.0.0/4"; print " domain:"; print " - \"+.google.com\""; print " - \"+.facebook.com\""; print " - \"+.youtube.com\""; print " nameserver-policy:"; print " \"geosite:cn,private\":"; print " - https://doh.pub/dns-query"; print " - https://dns.alidns.com/dns-query"; print " \"geosite:category-ads-all\": rcode://success"; print "proxies:"; print "proxy-groups:"; print " - name: Proxy"; print " type: select"; print " proxies:"; print " - auto"; print " - name: auto"; print " type: url-test"; print " proxies:"; print " url: \"https://cp.cloudflare.com/generate_204\""; print " interval: 300"; print "rules:"; print " - GEOSITE,private,DIRECT"; print " - GEOSITE,category-ads-all,REJECT"; print " - GEOSITE,cn,DIRECT"; print " - GEOIP,cn,DIRECT"; print " - MATCH,Proxy"; }' > "${clash_yaml}"
- sed -i'' -e '/^ - "+\.google\.com"/s/"/'\''/g' "${clash_yaml}"
- sed -i'' -e '/^ - "+\.facebook\.com"/s/"/'\''/g' "${clash_yaml}"
- sed -i'' -e '/^ - "+\.youtube\.com"/s/"/'\''/g' "${clash_yaml}"
- fi
- }
- function write_naive_client_file() {
- local naive_client_file="$naive_client_filename"
- awk -v naive_client_file="$naive_client_file" 'BEGIN { print "{"; print " \"listen\": \"socks://127.0.0.1:1080\","; print " \"proxy\": \"https://user_name:user_password@server_name:listen_port\""; print "}" }' > "$naive_client_file"
- }
- function generate_shadowsocks_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local proxy_name
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- while true; do
- proxy_name="ss-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v ss_method="$ss_method" -v ss_password="$ss_password" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"shadowsocks\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"method\": \"" ss_method "\", "; print " \"password\": \"" ss_password "\"" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_shadowsocks_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local proxy_name
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- while true; do
- proxy_name="ss-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v ss_method="$ss_method" -v ss_password="$ss_password" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"shadowsocks\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"method\": \"" ss_method "\", "; print " \"password\": \"" ss_password "\"" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_shadowsocks_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="ss-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v ss_method="$ss_method" -v ss_password="$ss_password" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: ss"; print " server:", local_ip; print " port:", listen_port; print " cipher:", ss_method; print " password:", "\"" ss_password "\""; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_juicity_win_client_config() {
- local client_file="/usr/local/etc/juicity/client.json"
- local server_name="$domain"
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- awk -v listen_port="$listen_port" -v server_value="$server_value" -v user_uuids="$user_uuids" -v user_passwords="$user_passwords" -v server_name="$server_name" -v tls_insecure="$tls_insecure" -v congestion_control="$congestion_control" 'BEGIN { print "{"; printf " \"listen\": \":%s\",\n", 1080; printf " \"server\": \"%s:%s\",\n", server_value, listen_port; printf " \"uuid\": \"%s\",\n", user_uuids; printf " \"password\": \"%s\",\n", user_passwords; printf " \"sni\": \"%s\",\n", server_name; printf " \"allow_insecure\": %s,\n", tls_insecure; printf " \"congestion_control\": \"%s\",\n", congestion_control; printf " \"log_level\": \"info\"\n"; print "}"}' > "$client_file"
- echo "客户端配置文件已保存至$client_file,请下载后使用!"
- }
- function generate_tuic_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="tuic-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v user_password="$user_password" -v congestion_control="$congestion_control" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"tuic\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\", "; print " \"password\": \"" user_password "\", "; print " \"congestion_control\": \""congestion_control"\","; print " \"udp_relay_mode\": \"native\","; print " \"zero_rtt_handshake\": false,"; print " \"heartbeat\": \"10s\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\", "; print " \"alpn\": ["; print " \"h3\""; print " ]" ech_client_config ""; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_tuic_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="tuic-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v user_password="$user_password" -v congestion_control="$congestion_control" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"tuic\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\", "; print " \"password\": \"" user_password "\", "; print " \"congestion_control\": \""congestion_control"\","; print " \"udp_relay_mode\": \"native\","; print " \"zero_rtt_handshake\": false,"; print " \"heartbeat\": \"10s\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\", "; print " \"alpn\": ["; print " \"h3\""; print " ]" ech_client_config ""; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_tuic_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- while true; do
- proxy_name="tuic-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v user_password="$user_password" -v congestion_control="$congestion_control" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " server:", server_value; print " port:", listen_port; print " type: tuic"; print " uuid:", user_uuid; print " password:", user_password; print " sni:", server_name; print " alpn: [h3]"; print " request-timeout: 8000"; print " udp-relay-mode: native"; print " skip-cert-verify:", tls_insecure; print " congestion-controller:", congestion_control; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_socks_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local proxy_name
- while true; do
- proxy_name="socks-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_name="$user_name" -v user_password="$user_password" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"socks\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"username\": \"" user_name "\", "; print " \"password\": \"" user_password "\" "; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_socks_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local proxy_name
- while true; do
- proxy_name="socks-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_name="$user_name" -v user_password="$user_password" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"socks\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"username\": \"" user_name "\", "; print " \"password\": \"" user_password "\" "; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_socks_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="socks-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_name="$user_name" -v user_password="$user_password" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: socks5"; print " server:", local_ip; print " port:", listen_port; print " username:", user_name; print " password:", user_password; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_Hysteria_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$obfs_password" ]; then
- obfs_config="\n \"obfs\": \"$obfs_password\","
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="Hysteria-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v up_mbps="$up_mbps" -v down_mbps="$down_mbps" -v obfs_config="$obfs_config" -v user_password="$user_password" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"hysteria\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"up_mbps\": " down_mbps ", "; print " \"down_mbps\": " up_mbps ","obfs_config""; print " \"auth_str\": \""user_password"\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\", "; print " \"alpn\": ["; print " \"h3\""; print " ]" ech_client_config ""; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_Hysteria_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$obfs_password" ]; then
- obfs_config="\n \"obfs\": \"$obfs_password\","
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="Hysteria-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v up_mbps="$up_mbps" -v down_mbps="$down_mbps" -v obfs_config="$obfs_config" -v user_password="$user_password" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"hysteria\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"up_mbps\": " down_mbps ", "; print " \"down_mbps\": " up_mbps ","obfs_config""; print " \"auth_str\": \""user_password"\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\", "; print " \"alpn\": ["; print " \"h3\""; print " ]" ech_client_config ""; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_Hysteria_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$obfs_password" ]; then
- obfs_config="
- obfs: $obfs_password"
- fi
- while true; do
- proxy_name="hysteria-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v up_mbps="$up_mbps" -v down_mbps="$down_mbps" -v user_password="$user_password" -v obfs_config="$obfs_config" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: hysteria"; print " server:", server_value; print " port:", listen_port; print " auth-str:", user_password obfs_config; print " sni:", server_name; print " skip-cert-verify:", tls_insecure; print " alpn:"; print " - h3"; print " protocol: udp"; print " up: \"" down_mbps " Mbps\""; print " down: \"" up_mbps " Mbps\""; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vmess_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local proxy_name
- local server_name="$domain"
- local server_value
- local tls_insecure
- if [[ -z "$domain" && -n "$domain_name" ]]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- elif [[ -z "$domain" && -z "$domain_name" ]]; then
- server_value="$local_ip"
- elif [[ -z "$domain_name" && -n "$domain" ]]; then
- server_name="$domain"
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="vmess-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file"; then
- break
- fi
- done
- if [[ -n "$domain" || -n "$domain_name" ]]; then
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_config="$transport_config" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"vmess\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\"," transport_config " "; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\"" ech_client_config ""; print " },"; print " \"security\": \"auto\","; print " \"alter_id\": 0,"; print " \"packet_encoding\": \"xudp\"" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- else
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_config="$transport_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"vmess\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\"," transport_config " "; print " \"security\": \"auto\","; print " \"alter_id\": 0,"; print " \"packet_encoding\": \"xudp\"" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- fi
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_vmess_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local proxy_name
- local server_name="$domain"
- local server_value
- local tls_insecure
- if [[ -z "$domain" && -n "$domain_name" ]]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- elif [[ -z "$domain" && -z "$domain_name" ]]; then
- server_value="$local_ip"
- elif [[ -z "$domain_name" && -n "$domain" ]]; then
- server_name="$domain"
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="vmess-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file"; then
- break
- fi
- done
- if [[ -n "$domain" || -n "$domain_name" ]]; then
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_config="$transport_config" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"vmess\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\"," transport_config " "; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\"" ech_client_config ""; print " },"; print " \"security\": \"auto\","; print " \"alter_id\": 0,"; print " \"packet_encoding\": \"xudp\"" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- else
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_config="$transport_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"vmess\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\"," transport_config " "; print " \"security\": \"auto\","; print " \"alter_id\": 0,"; print " \"packet_encoding\": \"xudp\"" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- fi
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_vmess_tcp_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="vmess-tcp-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vmess"; print " server:", local_ip; print " port:", listen_port; print " uuid:", user_uuid; print " alterId: 0"; print " cipher: auto"; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vmess_tcp_tls_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- while true; do
- proxy_name="vmess-tcp-tls-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vmess"; print " server:", server_value; print " port:", listen_port; print " uuid:", user_uuid; print " alterId: 0"; print " cipher: auto"; print " tls: true"; print " skip-cert-verify:", tls_insecure; print " servername: " server_name; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vmess_ws_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="vmess-ws-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_path="$transport_path" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vmess"; print " server:", local_ip; print " port:", listen_port; print " uuid:", user_uuid; print " alterId: 0"; print " cipher: auto"; print " network: ws"; print " ws-opts:"; print " path: " transport_path; print " max-early-data: 2048"; print " early-data-header-name: Sec-WebSocket-Protocol"; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vmess_ws_tls_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- while true; do
- proxy_name="vmess-ws-tls-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_path="$transport_path" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vmess"; print " server:", server_value; print " port:", listen_port; print " uuid:", user_uuid; print " alterId: 0"; print " cipher: auto"; print " network: ws"; print " tls: true"; print " skip-cert-verify:", tls_insecure; print " servername:", server_name; print " ws-opts:"; print " path: " transport_path; print " max-early-data: 2048"; print " early-data-header-name: Sec-WebSocket-Protocol"; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vmess_grpc_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="vmess-grpc-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_service_name="$transport_service_name" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vmess"; print " server:", local_ip; print " port:", listen_port; print " uuid:", user_uuid; print " alterId: 0"; print " cipher: auto"; print " network: grpc"; print " grpc-opts:"; print " grpc-service-name:", "\"" transport_service_name "\""; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vmess_grpc_tls_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- while true; do
- proxy_name="vmess-grpc-tls-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_service_name="$transport_service_name" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vmess"; print " server:", server_value; print " port:", listen_port; print " uuid:", user_uuid; print " alterId: 0"; print " cipher: auto"; print " network: grpc"; print " tls: true"; print " skip-cert-verify:", tls_insecure; print " servername:", server_name; print " grpc-opts:"; print " grpc-service-name:", "\"" transport_service_name "\""; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_http_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="http-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_name="$user_name" -v user_password="$user_password" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"http\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"username\": \"" user_name "\", "; print " \"password\": \"" user_password "\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\"" ech_client_config ""; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_http_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="http-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_name="$user_name" -v user_password="$user_password" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"http\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"username\": \"" user_name "\", "; print " \"password\": \"" user_password "\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\"" ech_client_config ""; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_http_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- while true; do
- proxy_name="http-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_name="$user_name" -v user_password="$user_password" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: http"; print " server:", server_value; print " port:", listen_port; print " username:", user_name; print " password:", user_password; print " tls: true"; print " sni:", server_name; print " skip-cert-verify:", tls_insecure; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_Hysteria2_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$obfs_password" ]; then
- obfs_config="\n \"obfs\": {\n \"type\": \"salamander\",\n \"password\": \"$obfs_password\"\n },"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="Hysteria2-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v up_mbps="$up_mbps" -v down_mbps="$down_mbps" -v obfs_config="$obfs_config" -v user_password="$user_password" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"hysteria2\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"up_mbps\": " down_mbps ", "; print " \"down_mbps\": " up_mbps ","obfs_config""; print " \"password\": \"" user_password "\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\", "; print " \"alpn\": ["; print " \"h3\""; print " ]" ech_client_config ""; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_Hysteria2_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$obfs_password" ]; then
- obfs_config="\n \"obfs\": {\n \"type\": \"salamander\",\n \"password\": \"$obfs_password\"\n },"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="Hysteria2-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v up_mbps="$up_mbps" -v down_mbps="$down_mbps" -v obfs_config="$obfs_config" -v user_password="$user_password" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"hysteria2\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"up_mbps\": " down_mbps ", "; print " \"down_mbps\": " up_mbps ","obfs_config""; print " \"password\": \"" user_password "\","; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\", "; print " \"alpn\": ["; print " \"h3\""; print " ]" ech_client_config ""; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_Hysteria2_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$obfs_password" ]; then
- obfs_config="
- obfs: salamander
- obfs-password: $obfs_password"
- fi
- while true; do
- proxy_name="hysteria2-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v up_mbps="$up_mbps" -v down_mbps="$down_mbps" -v user_password="$user_password" -v obfs_config="$obfs_config" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: hysteria2"; print " server:", server_value; print " port:", listen_port; print " password:", user_password obfs_config; print " alpn:"; print " - h3"; print " sni:", server_name; print " skip-cert-verify:", tls_insecure; print " up: \"" down_mbps " Mbps\""; print " down: \"" up_mbps " Mbps\""; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vless_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local proxy_name
- local server_name_in_config=$(jq -r '.inbounds[0].tls.server_name' "$config_file")
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- while true; do
- proxy_name="vless-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file"; then
- break
- fi
- done
- if [ "$server_name_in_config" != "null" ]; then
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v flow_type="$flow_type" -v public_key="$public_key" -v short_id="$short_id" -v transport_config="$transport_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"vless\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\", "; print " \"flow\": \"" flow_type "\"," transport_config ""; print " \"tls\": {"; print " \"enabled\": true,"; print " \"server_name\": \"" server_name "\", "; print " \"utls\": {"; print " \"enabled\": true,"; print " \"fingerprint\": \"chrome\""; print " },"; print " \"reality\": {"; print " \"enabled\": true,"; print " \"public_key\": \"" public_key "\","; print " \"short_id\": \"" short_id "\""; print " }"; print " }" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- else
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v flow_type="$flow_type" -v transport_config="$transport_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"vless\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\"," transport_config ""; print " \"flow\": \"" flow_type "\"" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- fi
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_vless_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local proxy_name
- local server_name_in_config=$(jq -r '.inbounds[0].tls.server_name' "$config_file")
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- while true; do
- proxy_name="vless-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file"; then
- break
- fi
- done
- if [ "$server_name_in_config" != "null" ]; then
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v flow_type="$flow_type" -v public_key="$public_key" -v short_id="$short_id" -v transport_config="$transport_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"vless\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\", "; print " \"flow\": \"" flow_type "\"," transport_config ""; print " \"tls\": {"; print " \"enabled\": true,"; print " \"server_name\": \"" server_name "\", "; print " \"utls\": {"; print " \"enabled\": true,"; print " \"fingerprint\": \"chrome\""; print " },"; print " \"reality\": {"; print " \"enabled\": true,"; print " \"public_key\": \"" public_key "\","; print " \"short_id\": \"" short_id "\""; print " }"; print " }" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- else
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v flow_type="$flow_type" -v transport_config="$transport_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"vless\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"uuid\": \"" user_uuid "\"," transport_config ""; print " \"flow\": \"" flow_type "\"" multiplex_client_config ""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- fi
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_vless_tcp_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="vless-tcp-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vless"; print " server:", local_ip; print " port:", listen_port; print " uuid:", user_uuid; print " network: tcp"; print " udp: true"; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vless_ws_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="vless-ws-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_path="$transport_path" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vless"; print " server:", local_ip; print " port:", listen_port; print " uuid:", user_uuid; print " network: ws"; print " udp: true"; print " ws-opts:"; print " path: " transport_path; print " max-early-data: 2048"; print " early-data-header-name: Sec-WebSocket-Protocol"; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vless_grpc_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="vless-grpc-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v transport_service_name="$transport_service_name" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vless"; print " server:", local_ip; print " port:", listen_port; print " uuid:", user_uuid; print " network: grpc"; print " udp: true"; print " grpc-opts:"; print " grpc-service-name:", "\"" transport_service_name "\""; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vless_reality_vision_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="vless-reality-vision-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v public_key="$public_key" -v short_id="$short_id" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vless"; print " server:", local_ip; print " port:", listen_port; print " uuid:", user_uuid; print " network: tcp"; print " udp: true"; print " tls: true"; print " flow: xtls-rprx-vision"; print " servername:", server_name; print " reality-opts:"; print " public-key:", public_key; print " short-id:", short_id; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_vless_reality_grpc_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="vless-reality-grpc-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v server_name="$server_name" -v listen_port="$listen_port" -v user_uuid="$user_uuid" -v public_key="$public_key" -v short_id="$short_id" -v transport_service_name="$transport_service_name" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: vless"; print " server:", local_ip; print " port:", listen_port; print " uuid:", user_uuid; print " network: grpc"; print " udp: true"; print " tls: true"; print " flow: "; print " servername:", server_name; print " reality-opts:"; print " public-key:", public_key; print " short-id:", short_id; print " grpc-opts:"; print " grpc-service-name:", "\"" transport_service_name "\""; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_trojan_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local proxy_name
- local server_name="$domain"
- local server_value
- local tls_insecure
- if [[ -z "$domain" && -n "$domain_name" ]]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- elif [[ -z "$domain" && -z "$domain_name" ]]; then
- server_value="$local_ip"
- elif [[ -z "$domain_name" && -n "$domain" ]]; then
- server_name="$domain"
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="trojan-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file"; then
- break
- fi
- done
- if [[ -n "$domain" || -n "$domain_name" ]]; then
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_password="$user_password" -v transport_config="$transport_config" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"trojan\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"password\": \"" user_password "\"," transport_config " "; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\"" ech_client_config ""; print " }"multiplex_client_config""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- else
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_password="$user_password" -v transport_config="$transport_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"trojan\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port "," transport_config " "; print " \"password\": \"" user_password "\""multiplex_client_config""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- fi
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_trojan_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local proxy_name
- local server_name="$domain"
- local server_value
- local tls_insecure
- if [[ -z "$domain" && -n "$domain_name" ]]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- elif [[ -z "$domain" && -z "$domain_name" ]]; then
- server_value="$local_ip"
- elif [[ -z "$domain_name" && -n "$domain" ]]; then
- server_name="$domain"
- server_value="$domain"
- tls_insecure="false"
- fi
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- if [ -n "$ech_config" ]; then
- ech_client_config=",\n \"ech\": {\n \"enabled\": true,\n \"pq_signature_schemes_enabled\": true,\n \"dynamic_record_sizing_disabled\": false,\n \"config\": [\n$ech_config\n ]\n }"
- fi
- while true; do
- proxy_name="trojan-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file"; then
- break
- fi
- done
- if [[ -n "$domain" || -n "$domain_name" ]]; then
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_password="$user_password" -v transport_config="$transport_config" -v tls_insecure="$tls_insecure" -v ech_client_config="$ech_client_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"trojan\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" server_value "\", "; print " \"server_port\": " listen_port ","; print " \"password\": \"" user_password "\"," transport_config " "; print " \"tls\": {"; print " \"enabled\": true,"; print " \"insecure\": " tls_insecure ","; print " \"server_name\": \"" server_name "\"" ech_client_config ""; print " }"multiplex_client_config""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- else
- awk -v proxy_name="$proxy_name" -v local_ip="$local_ip" -v listen_port="$listen_port" -v user_password="$user_password" -v transport_config="$transport_config" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"trojan\","; print " \"tag\": \"" proxy_name "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port "," transport_config " "; print " \"password\": \"" user_password "\""multiplex_client_config""; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- fi
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_trojan_tcp_tls_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- while true; do
- proxy_name="trojan-tcp-tls-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_password="$user_password" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: trojan"; print " server:", server_value; print " port:", listen_port; print " password:", user_password; print " udp: true"; print " sni:", server_name; print " skip-cert-verify:", tls_insecure; print " alpn:"; print " - h2"; print " - http/1.1"; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_trojan_ws_tls_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- while true; do
- proxy_name="trojan-ws-tls-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_password="$user_password" -v transport_path="$transport_path" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: trojan"; print " server:", server_value; print " port:", listen_port; print " password:", "\"" user_password "\""; print " network: ws"; print " sni:", server_name; print " skip-cert-verify:", tls_insecure; print " udp: true"; print " ws-opts:"; print " path:", transport_path; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_trojan_grpc_tls_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local server_name="$domain"
- local proxy_name
- local server_value
- local tls_insecure
- if [ -z "$domain" ]; then
- server_name="$domain_name"
- server_value="$local_ip"
- tls_insecure="true"
- else
- server_value="$domain"
- tls_insecure="false"
- fi
- while true; do
- proxy_name="trojan-grpc-tls-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v server_value="$server_value" -v server_name="$server_name" -v listen_port="$listen_port" -v user_password="$user_password" -v transport_service_name="$transport_service_name" -v tls_insecure="$tls_insecure" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: trojan"; print " server:", server_value; print " port:", listen_port; print " password:", "\"" user_password "\""; print " network: grpc"; print " sni:", server_name; print " udp: true"; print " skip-cert-verify:", tls_insecure; print " grpc-opts:"; print " grpc-service-name:", "\"" transport_service_name "\""; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_shadowtls_win_client_config() {
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local proxy_name
- local shadowtls_out
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- while true; do
- proxy_name="shadowtls-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- shadowtls_out="stl-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$win_client_file" && ! grep -q "name: $shadowtls_out" "$win_client_file" && [ "$proxy_name" != "$shadowtls_out" ]; then
- break
- fi
- done
- awk -v shadowtls_out="$shadowtls_out" -v proxy_name="$proxy_name" -v method="$method" -v ss_password="$ss_password" -v local_ip="$local_ip" -v listen_port="$listen_port" -v stls_password="$stls_password" -v user_input="$user_input" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"shadowsocks\","; print " \"tag\": \"" proxy_name "\","; print " \"method\": \"" method "\", "; print " \"password\": \"" ss_password "\","; print " \"detour\": \"" shadowtls_out "\""multiplex_client_config""; print " },"; print " {"; print " \"type\": \"shadowtls\","; print " \"tag\": \"" shadowtls_out "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"version\": 3, "; print " \"password\": \""stls_password"\", "; print " \"tls\": {"; print " \"enabled\": true,"; print " \"server_name\": \"" user_input "\", "; print " \"utls\": {"; print " \"enabled\": true,"; print " \"fingerprint\": \"chrome\" "; print " }"; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- }
- function generate_shadowtls_phone_client_config() {
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local proxy_name
- local shadowtls_out
- if [ -n "$multiplex_config" ] && [ -n "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false,\n \"brutal\": {\n \"enabled\": true,\n \"up_mbps\": $down_mbps,\n \"down_mbps\": $up_mbps\n }\n }"
- elif [ -n "$multiplex_config" ] && [ -z "$brutal_config" ]; then
- multiplex_client_config=",\n \"multiplex\": {\n \"enabled\": true,\n \"protocol\": \"h2mux\",\n \"max_connections\": 1,\n \"min_streams\": 4,\n \"padding\": false\n }"
- fi
- while true; do
- proxy_name="shadowtls-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- shadowtls_out="stl-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$phone_client_file" && ! grep -q "name: $shadowtls_out" "$phone_client_file" && [ "$proxy_name" != "$shadowtls_out" ]; then
- break
- fi
- done
- awk -v shadowtls_out="$shadowtls_out" -v proxy_name="$proxy_name" -v method="$method" -v ss_password="$ss_password" -v local_ip="$local_ip" -v listen_port="$listen_port" -v stls_password="$stls_password" -v user_input="$user_input" -v multiplex_client_config="$multiplex_client_config" '
- /^ "outbounds": \[/ {print; getline; print " {"; print " \"type\": \"shadowsocks\","; print " \"tag\": \"" proxy_name "\","; print " \"method\": \"" method "\", "; print " \"password\": \"" ss_password "\","; print " \"detour\": \"" shadowtls_out "\""multiplex_client_config""; print " },"; print " {"; print " \"type\": \"shadowtls\","; print " \"tag\": \"" shadowtls_out "\","; print " \"server\": \"" local_ip "\", "; print " \"server_port\": " listen_port ","; print " \"version\": 3, "; print " \"password\": \""stls_password"\", "; print " \"tls\": {"; print " \"enabled\": true,"; print " \"server_name\": \"" user_input "\", "; print " \"utls\": {"; print " \"enabled\": true,"; print " \"fingerprint\": \"chrome\" "; print " }"; print " }"; print " },";}
- /^ "outbounds": \[/ {print; getline; if ($0 ~ /^ \],$/) {print " \"" proxy_name "\""} else {print " \"" proxy_name "\", "} }
- {print}' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- }
- function generate_shadowtls_yaml() {
- local filename="/usr/local/etc/sing-box/clash.yaml"
- local proxy_name
- while true; do
- proxy_name="shadowtls-$(head /dev/urandom | tr -dc '0-9' | head -c 4)"
- if ! grep -q "name: $proxy_name" "$filename"; then
- break
- fi
- done
- awk -v proxy_name="$proxy_name" -v method="$method" -v ss_password="$ss_password" -v local_ip="$local_ip" -v listen_port="$listen_port" -v stls_password="$stls_password" -v user_input="$user_input" '/^proxies:$/ {print; print " - name: " proxy_name; print " type: ss"; print " server:", local_ip; print " port:", listen_port; print " cipher:", method; print " password:", "\"" ss_password "\""; print " plugin: shadow-tls"; print " plugin-opts:"; print " host: \"" user_input "\""; print " password:", "\"" stls_password "\""; print " version: 3"; print ""; next} /- name: Proxy/ { print; flag_proxy=1; next } flag_proxy && flag_proxy++ == 3 { print " - " proxy_name } /- name: auto/ { print; flag_auto=1; next } flag_auto && flag_auto++ == 3 { print " - " proxy_name } 1' "$filename" > temp_file && mv temp_file "$filename"
- }
- function generate_naive_win_client_config() {
- local naive_client_file="$naive_client_filename"
- sed -i -e "s,user_name,$user_name," -e "s,user_password,$user_password," -e "s,listen_port,$listen_port," -e "s,server_name,$domain," "$naive_client_file"
- echo "电脑端配置文件已保存至$naive_client_file,请下载后使用!"
- }
- function extract_types_tags() {
- local config_file="/usr/local/etc/sing-box/config.json"
- filtered_tags=()
- types=()
- tags=($(jq -r '.inbounds[] | select(.tag != null) | .tag' "$config_file"))
- detour_tag=$(jq -r '.inbounds[] | select(.type == "shadowtls") | .detour' "$config_file")
- wireguard_type=$(jq -r '.outbounds[] | select(.type == "wireguard" and .tag == "wireguard-out") | .type' "$config_file")
- if [ -z "$tags" ] && [ -z "$wireguard_type" ]; then
- echo "未检测到节点配置,请搭建节点后再使用本选项!"
- exit 0
- fi
- filtered_tags=()
- for tag in "${tags[@]}"; do
- if [ "$tag" != "$detour_tag" ]; then
- filtered_tags+=("$tag")
- fi
- done
- max_length=0
- for tag in "${filtered_tags[@]}"; do
- tag_length=${#tag}
- if ((tag_length > max_length)); then
- max_length=$tag_length
- fi
- done
- for ((i=0; i<${#filtered_tags[@]}; i++)); do
- type=$(jq -r --arg tag "${filtered_tags[$i]}" '.inbounds[] | select(.tag == $tag) | .type' "$config_file")
- types[$i]=$type
- printf "%d).协议类型: %-20s 入站标签: %s\n" "$((i+1))" "$type" "${filtered_tags[$i]}"
- done
- if [ ! -z "$wireguard_type" ]; then
- types[$i]=$wireguard_type
- printf "%d).协议类型: %-20s 出站标签: %s\n" "$((i+1))" "$wireguard_type" "wireguard-out"
- fi
- }
- function delete_choice() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local clash_yaml="/usr/local/etc/sing-box/clash.yaml"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local temp_json="/usr/local/etc/sing-box/temp.json"
- local temp_yaml="/usr/local/etc/sing-box/temp.yaml"
- extract_types_tags
- valid_choice=false
- while [ "$valid_choice" == false ]; do
- read -p "请选择要删除的节点配置(输入对应的数字): " choice
- if [[ ! $choice =~ ^[0-9]+$ || $choice -lt 1 || $choice -gt ${#types[@]} ]]; then
- echo -e "${RED}错误:无效的选择,请重新输入!${NC}"
- else
- valid_choice=true
- fi
- done
- selected_tag="${filtered_tags[$choice-1]}"
- selected_type="${types[$choice-1]}"
- listen_port=$(jq -r --arg selected_tag "$selected_tag" '.inbounds[] | select(.tag == $selected_tag) | .listen_port' "$config_file" | awk '{print int($0)}')
- if [ "$selected_type" == "wireguard" ]; then
- jq '.outbounds |= map(select(.tag != "warp-IPv4-out" and .tag != "warp-IPv6-out" and .tag != "wireguard-out"))' "$config_file" > "$temp_json"
- mv "$temp_json" "$config_file"
- jq '.route.rules |= map(select(.outbound != "warp-IPv4-out" and .outbound != "warp-IPv6-out"))' "$config_file" > "$temp_json"
- mv "$temp_json" "$config_file"
- else
- detour_tag=$(jq -r --arg selected_tag "$selected_tag" '.inbounds[] | select(.type == "shadowtls" and .tag == $selected_tag) | .detour' "$config_file")
- jq --arg selected_tag "$selected_tag" --arg detour_tag "$detour_tag" '.inbounds |= map(select(.tag != $selected_tag and .tag != $detour_tag))' "$config_file" > "$temp_json"
- mv "$temp_json" "$config_file"
- jq --arg selected_tag "$selected_tag" '.route.rules |= map(select(.inbound[0] != $selected_tag))' "$config_file" > "$temp_json"
- mv "$temp_json" "$config_file"
- fi
- if [ "$selected_type" != "wireguard" ]; then
- awk -v port="$listen_port" '$0 ~ "监听端口: " port {print; in_block=1; next} in_block && NF == 0 {in_block=0} !in_block' "$output_file" > "$output_file.tmp1"
- mv "$output_file.tmp1" "$output_file"
- awk -v port="$listen_port" '$0 ~ "监听端口: " port {start=NR; next} {lines[NR]=$0} END {for (i=1; i<=NR; i++) if (i < start - 4 || i > start) print lines[i]}' "$output_file" > "$output_file.tmp2"
- mv "$output_file.tmp2" "$output_file"
- sed -i '/./,$!d' "$output_file"
- fi
- if [ -f "$clash_yaml" ]; then
- get_clash_tags=$(awk '/proxies:/ {in_proxies_block=1} in_proxies_block && /- name:/ {name = $3} in_proxies_block && /port:/ {port = $2; print "Name:", name, "Port:", port}' "$clash_yaml" > "$temp_yaml")
- matching_clash_tag=$(grep "Port: $listen_port" "$temp_yaml" | awk '{print $2}')
- fi
- if [ -n "$listen_port" ]; then
- phone_matching_tag=$(jq -r --argjson listen_port "$listen_port" '.outbounds[] | select(.server_port == $listen_port) | .tag' "$phone_client_file")
- win_matching_tag=$(jq -r --argjson listen_port "$listen_port" '.outbounds[] | select(.server_port == $listen_port) | .tag' "$win_client_file")
- fi
- jq --arg tag "$phone_matching_tag" '.outbounds |= map(select(.tag != $tag))' "$phone_client_file" > "$temp_json"
- mv "$temp_json" "$phone_client_file"
- jq --arg tag "$win_matching_tag" '.outbounds |= map(select(.tag != $tag))' "$win_client_file" > "$temp_json"
- mv "$temp_json" "$win_client_file"
- if [ -n "$matching_clash_tag" ] && [ "$selected_type" != "wireguard" ]; then
- sed -i "/^ - name: $matching_clash_tag$/,/^\s*$/d" "$clash_yaml"
- sed -i "/proxy-groups:/,/^\s*$/ {/ - $matching_clash_tag/d}" "$clash_yaml"
- fi
- phone_matching_detour=$(jq -r --arg phone_matching_tag "$phone_matching_tag" '.outbounds[] | select(.detour == $phone_matching_tag) | .detour' "$phone_client_file")
- win_matching_detour=$(jq -r --arg win_matching_tag "$win_matching_tag" '.outbounds[] | select(.detour == $win_matching_tag) | .detour' "$win_client_file")
- phone_matching_detour_tag=$(jq -r --arg phone_matching_detour "$phone_matching_detour" '.outbounds[] | select(.detour == $phone_matching_detour) | .tag' "$phone_client_file")
- win_matching_detour_tag=$(jq -r --arg win_matching_detour "$win_matching_detour" '.outbounds[] | select(.detour == $win_matching_detour) | .tag' "$win_client_file")
- awk -v phone_matching_tag="$phone_matching_tag" '!/^ "outbounds": \[$/,/^\s*]/{if (!($0 ~ "^ * \"" phone_matching_tag "\"")) print; else next; }' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- awk -v win_matching_tag="$win_matching_tag" '!/^ "outbounds": \[$/,/^\s*]/{if (!($0 ~ "^ * \"" win_matching_tag "\"")) print; else next; }' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- if [ "$phone_matching_tag" == "$phone_matching_detour" ]; then
- jq --arg phone_matching_detour "$phone_matching_detour" '.outbounds |= map(select(.detour != $phone_matching_detour))' "$phone_client_file" > "$temp_json"
- mv "$temp_json" "$phone_client_file"
- awk -v phone_matching_detour_tag="$phone_matching_detour_tag" '!/^ "outbounds": \[$/,/^\s*]/{if (!($0 ~ "^ * \"" phone_matching_detour_tag "\"")) print; else next; }' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- fi
- if [ "$win_matching_tag" == "$win_matching_detour" ]; then
- jq --arg win_matching_detour "$win_matching_detour" '.outbounds |= map(select(.detour != $win_matching_detour))' "$win_client_file" > "$temp_json"
- mv "$temp_json" "$win_client_file"
- awk -v win_matching_detour_tag="$win_matching_detour_tag" '!/^ "outbounds": \[$/,/^\s*]/{if (!($0 ~ "^ * \"" win_matching_detour_tag "\"")) print; else next; }' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- fi
- awk '{if ($0 ~ /],$/ && p ~ /,$/) sub(/,$/, "", p); if (NR > 1) print p; p = $0;}END{print p;}' "$phone_client_file" > "$phone_client_file.tmp"
- mv "$phone_client_file.tmp" "$phone_client_file"
- awk '{if ($0 ~ /],$/ && p ~ /,$/) sub(/,$/, "", p); if (NR > 1) print p; p = $0;}END{print p;}' "$win_client_file" > "$win_client_file.tmp"
- mv "$win_client_file.tmp" "$win_client_file"
- [ -f "$temp_yaml" ] && rm "$temp_yaml"
- if ! jq -e 'select(.inbounds[] | .listen == "::")' "$config_file" > /dev/null; then
- sed -i 's/"rules": \[\]/"rules": [\n ]/' "$config_file"
- sed -i 's/^ "inbounds": \[\],/ "inbounds": [\n ],/' "$config_file"
- sed -i 's/^ "outbounds": \[\],/ "outbounds": [\n ],/' "$win_client_file"
- sed -i 's/^ "outbounds": \[\],/ "outbounds": [\n ],/' "$phone_client_file"
- fi
- systemctl restart sing-box
- echo "已删除 $selected_type 的配置信息,服务端及客户端配置信息已更新,请下载新的配置文件使用!"
- }
- function display_naive_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local num_users=${#user_names[@]}
- echo -e "${CYAN}NaiveProxy 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $domain" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "用 户 名 密 码" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- for ((i=0; i<num_users; i++)); do
- local user_name="${user_names[i]}"
- local user_password="${user_passwords[i]}"
- printf "%-38s %s\n" "$user_name" "$user_password" | tee -a "$output_file"
- done
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function generate_naive_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local naive_client_file="$naive_client_filename"
- local num_users=${#user_names[@]}
- for ((i=0; i<num_users; i++)); do
- local user_name="${user_names[i]}"
- local user_password="${user_passwords[i]}"
- generate_naive_random_filename
- write_naive_client_file
- generate_naive_win_client_config "$user_name" "$user_password" "$listen_port" "$domain"
- done
- }
- function display_Direct_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local override_address=$(jq -r '.inbounds[0].override_address' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- echo -e "${CYAN}Direct 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "中转地址: $local_ip" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "目标地址: $override_address" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "目标端口: $override_port" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_juicity_config() {
- local config_file="/usr/local/etc/juicity/config.json"
- local output_file="/usr/local/etc/juicity/output.txt"
- local server_address
- local congestion_control=$(jq -r '.congestion_control' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- if [ -z "$domain" ]; then
- server_address="$local_ip"
- else
- server_address="$domain"
- fi
- echo -e "${CYAN}Juicity 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $server_address" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "UUID:$user_uuids 密码:$user_passwords " | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "拥塞控制算法: $congestion_control" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "分享链接:"
- juicity-server generate-sharelink -c "$config_file"
- generate_juicity_win_client_config
- echo "配置信息已保存至 $output_file"
- }
- function display_http_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local num_users=${#user_names[@]}
- local server_address
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- if [ -z "$domain" ]; then
- server_address="$local_ip"
- else
- server_address="$domain"
- fi
- echo -e "${CYAN}HTTP 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $server_address" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "用 户 名 密 码" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- for ((i=0; i<num_users; i++)); do
- local user_name="${user_names[i]}"
- local user_password="${user_passwords[i]}"
- printf "%-38s %s\n" "$user_name" "$user_password" | tee -a "$output_file"
- done
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_http_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- for ((i=0; i<${#user_passwords[@]}; i++)); do
- user_password="${user_passwords[$i]}"
- if [ "$enable_ech" = true ]; then
- write_phone_client_file
- write_win_client_file
- generate_http_win_client_config "$user_password"
- generate_http_phone_client_config "$user_password"
- else
- write_phone_client_file
- write_win_client_file
- generate_http_win_client_config "$user_password"
- generate_http_phone_client_config "$user_password"
- ensure_clash_yaml
- write_clash_yaml
- generate_http_yaml
- fi
- done
- if [ "$enable_ech" = true ]; then
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- else
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- echo "Clash配置文件已保存至 $clash_file ,请下载使用!"
- fi
- }
- function display_tuic_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local server_address
- local congestion_control=$(jq -r '.inbounds[0].congestion_control' "$config_file")
- local alpn=$(jq -r '.inbounds[0].tls.alpn[0]' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- if [ -z "$domain" ]; then
- server_address="$local_ip"
- else
- server_address="$domain"
- fi
- echo -e "${CYAN}TUIC 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $server_address" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "用户密码列表:" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- echo " 用户名 UUID 密码" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- for ((i=0; i<${#user_names[@]}; i++)); do
- user_name="${user_names[$i]}"
- user_uuid="${user_uuids[$i]}"
- user_password="${user_passwords[$i]}"
- printf "%-13s %-42s %s\n" "$user_name" "$user_uuid" "$user_password" | tee -a "$output_file"
- done
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "拥塞控制算法: $congestion_control" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "ALPN: $alpn" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_tuic_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local congestion_control=$(jq -r '.inbounds[0].congestion_control' "$config_file")
- local alpn=$(jq -r '.inbounds[0].tls.alpn[0]' "$config_file")
- local num_users=${#user_uuids[@]}
- for ((i=0; i<num_users; i++)); do
- local user_uuid="${user_uuids[i]}"
- local user_password="${user_passwords[i]}"
- if [ "$enable_ech" = true ]; then
- write_phone_client_file
- write_win_client_file
- generate_tuic_win_client_config "$user_uuid" "$user_password"
- generate_tuic_phone_client_config "$user_uuid" "$user_password"
- else
- write_phone_client_file
- write_win_client_file
- generate_tuic_win_client_config "$user_uuid" "$user_password"
- generate_tuic_phone_client_config "$user_uuid" "$user_password"
- ensure_clash_yaml
- write_clash_yaml
- generate_tuic_yaml
- fi
- done
- if [ "$enable_ech" = true ]; then
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- else
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- echo "Clash配置文件已保存至 $clash_file ,请下载使用!"
- fi
- }
- function display_Shadowsocks_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local ss_method=$(jq -r '.inbounds[0].method' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- echo -e "${CYAN}Shadowsocks 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $local_ip" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "加密方式: $ss_method" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "密码: $ss_passwords" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_Shadowsocks_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local ss_method=$(jq -r '.inbounds[0].method' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- write_phone_client_file
- write_win_client_file
- generate_shadowsocks_win_client_config
- generate_shadowsocks_phone_client_config
- ensure_clash_yaml
- write_clash_yaml
- generate_shadowsocks_yaml
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- echo "Clash配置文件已保存至 $clash_file ,请下载使用!"
- }
- function display_socks_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- echo -e "${CYAN}SOCKS 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $local_ip" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "用户密码列表:" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- echo "用户名 密码" | tee -a "$output_file"
- for ((i=0; i<${#user_names[@]}; i++)); do
- user_name="${user_names[$i]}"
- user_password="${user_passwords[$i]}"
- printf "%-35s %s\n" "$user_name" "$user_password" | tee -a "$output_file"
- done
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "节点配置信息已保存至 $output_file"
- }
- function display_socks_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local num_users=${#user_names[@]}
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- for ((i=0; i<num_users; i++)); do
- local user_name="${user_names[i]}"
- local user_password="${user_passwords[i]}"
- write_phone_client_file
- write_win_client_file
- generate_socks_win_client_config "$user_name" "$user_password"
- generate_socks_phone_client_config "$user_name" "$user_password"
- ensure_clash_yaml
- write_clash_yaml
- generate_socks_yaml
- done
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- echo "Clash配置文件已保存至 $clash_file ,请下载使用!"
- }
- function display_Hysteria_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local server_address
- local alpn=$(jq -r '.inbounds[0].tls.alpn[0]' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- if [ -z "$domain" ]; then
- server_address="$local_ip"
- else
- server_address="$domain"
- fi
- echo -e "${CYAN}Hysteria 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址:$server_address" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口:$listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "上行速度:${up_mbps}Mbps" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "下行速度:${down_mbps}Mbps" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "ALPN:$alpn" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "用户名 密码" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- for ((i=0; i<${#user_names[@]}; i++)); do
- user_name="${user_names[$i]}"
- user_password="${user_passwords[$i]}"
- printf "%-35s %s\n" "$user_name" "$user_password" | tee -a "$output_file"
- done
- if [ -n "$obfs_password" ]; then
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "obfs混淆密码:$obfs_password" | tee -a "$output_file"
- fi
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_Hysteria_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local alpn=$(jq -r '.inbounds[0].tls.alpn[0]' "$config_file")
- for ((i=0; i<${#user_passwords[@]}; i++)); do
- user_password="${user_passwords[$i]}"
- if [ "$enable_ech" = true ]; then
- write_phone_client_file
- write_win_client_file
- generate_Hysteria_win_client_config "$user_password"
- generate_Hysteria_phone_client_config "$user_password"
- else
- write_phone_client_file
- write_win_client_file
- generate_Hysteria_win_client_config "$user_password"
- generate_Hysteria_phone_client_config "$user_password"
- ensure_clash_yaml
- write_clash_yaml
- generate_Hysteria_yaml
- fi
- done
- if [ "$enable_ech" = true ]; then
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- else
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- echo "Clash配置文件已保存至 $clash_file ,请下载使用!"
- fi
- }
- function display_Hy2_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local server_address
- local alpn=$(jq -r '.inbounds[0].tls.alpn[0]' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- if [ -z "$domain" ]; then
- server_address="$local_ip"
- else
- server_address="$domain"
- fi
- echo -e "${CYAN}Hysteria2 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址:$server_address" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口:$listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "上行速度:${up_mbps}Mbps" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "下行速度:${down_mbps}Mbps" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "ALPN:$alpn" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "用户名 密码" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- for ((i=0; i<${#user_names[@]}; i++)); do
- user_name="${user_names[$i]}"
- user_password="${user_passwords[$i]}"
- printf "%-35s %s\n" "$user_name" "$user_password" | tee -a "$output_file"
- done
- if [ -n "$obfs_password" ]; then
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "QUIC 流量混淆器密码:$obfs_password" | tee -a "$output_file"
- fi
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_Hy2_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local alpn=$(jq -r '.inbounds[0].tls.alpn[0]' "$config_file")
- for ((i=0; i<${#user_passwords[@]}; i++)); do
- user_password="${user_passwords[$i]}"
- if [ "$enable_ech" = true ]; then
- write_phone_client_file
- write_win_client_file
- generate_Hysteria2_win_client_config "$user_password"
- generate_Hysteria2_phone_client_config "$user_password"
- else
- write_phone_client_file
- write_win_client_file
- generate_Hysteria2_win_client_config "$user_password"
- generate_Hysteria2_phone_client_config "$user_password"
- ensure_clash_yaml
- write_clash_yaml
- generate_Hysteria2_yaml
- fi
- done
- if [ "$enable_ech" = true ]; then
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- else
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- echo "Clash配置文件已保存至 $clash_file ,请下载使用!"
- fi
- }
- function display_reality_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local flow_type=$(jq -r '.inbounds[0].users[0].flow' "$config_file")
- local transport_type=$(jq -r '.inbounds[0].transport.type' "$config_file")
- local server_name=$(jq -r '.inbounds[0].tls.server_name' "$config_file")
- local target_server=$(jq -r '.inbounds[0].tls.reality.handshake.server' "$config_file")
- local transport_service_name=$(jq -r '.inbounds[0].transport.service_name' "$config_file")
- local lobal_public_key="$public_key"
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- if [[ "$flow_type" == "xtls-rprx-vision" ]]; then
- transport_type="tcp"
- fi
- echo -e "${CYAN}VLESS 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $local_ip" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "UUID列表:" | tee -a "$output_file"
- for ((i=0; i<${#user_uuids[@]}; i++)); do
- user_uuid="${user_uuids[$i]}"
- echo "$user_uuid"| tee -a "$output_file"
- done
- if [ -n "$flow_type" ]; then
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "流控类型: $flow_type" | tee -a "$output_file"
- fi
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- if [ "$transport_type" != "null" ]; then
- echo "传输协议: $transport_type" | tee -a "$output_file"
- if [ "$transport_type" == "ws" ]; then
- echo "路径: $transport_path" | tee -a "$output_file"
- elif [ "$transport_type" == "httpupgrade" ]; then
- echo "路径: $transport_path" | tee -a "$output_file"
- elif [ "$transport_type" == "grpc" ]; then
- echo "grpc-service-name: $transport_service_name" | tee -a "$output_file"
- fi
- else
- echo "传输协议: tcp" | tee -a "$output_file"
- fi
- if [ -n "$server_name" ] && [ "$server_name" != "null" ]; then
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "ServerName: $server_name" | tee -a "$output_file"
- fi
- if [ -n "$target_server" ] && [ "$target_server" != "null" ]; then
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "目标网站地址: $target_server" | tee -a "$output_file"
- fi
- if [ -n "$short_id" ]; then
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "Short ID:" | tee -a "$output_file"
- for ((i=0; i<${#short_ids[@]}; i++)); do
- short_id="${short_ids[$i]}"
- echo "$short_id" | tee -a "$output_file"
- done
- fi
- if [ -n "$public_key" ]; then
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "PublicKey: $public_key" | tee -a "$output_file"
- fi
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_reality_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local flow_type=$(jq -r '.inbounds[0].users[0].flow' "$config_file")
- local transport_type=$(jq -r '.inbounds[0].transport.type' "$config_file")
- local server_name=$(jq -r '.inbounds[0].tls.server_name' "$config_file")
- local target_server=$(jq -r '.inbounds[0].tls.reality.handshake.server' "$config_file")
- local transport_service_name=$(jq -r '.inbounds[0].transport.service_name' "$config_file")
- local lobal_public_key="$public_key"
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- for ((i=0; i<${#user_uuids[@]}; i++)); do
- local user_uuid="${user_uuids[$i]}"
- write_phone_client_file
- write_win_client_file
- if [[ "$server_name" == "null" ]] && [[ "$transport_type" == "null" ]]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vless_tcp_yaml
- generate_vless_win_client_config
- generate_vless_phone_client_config
- elif [[ "$server_name" == "null" ]] && [[ "$transport_type" == "ws" ]]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vless_ws_yaml
- generate_vless_win_client_config
- generate_vless_phone_client_config
- elif [[ "$server_name" == "null" ]] && [[ "$transport_type" == "grpc" ]]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vless_grpc_yaml
- generate_vless_win_client_config
- generate_vless_phone_client_config
- elif [[ "$server_name" == "null" ]] && [[ "$transport_type" == "httpupgrade" ]]; then
- generate_vless_win_client_config
- generate_vless_phone_client_config
- fi
- for ((j=0; j<${#short_ids[@]}; j++)); do
- local short_id="${short_ids[$j]}"
- write_phone_client_file
- write_win_client_file
- if [[ -n "$server_name" ]] && [[ "$server_name" != "null" ]] && [[ "$transport_type" == "null" ]]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vless_reality_vision_yaml
- generate_vless_win_client_config
- generate_vless_phone_client_config
- elif [[ -n "$server_name" ]] && [[ "$server_name" != "null" ]] && [[ "$transport_type" == "http" ]]; then
- generate_vless_win_client_config
- generate_vless_phone_client_config
- elif [[ -n "$server_name" ]] && [[ "$server_name" != "null" ]] && [[ "$transport_type" == "grpc" ]]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vless_reality_grpc_yaml
- generate_vless_win_client_config
- generate_vless_phone_client_config
- fi
- done
- done
- if [[ "$transport_type" != "http" && "$transport_type" != "httpupgrade" ]]; then
- echo "Clash配置文件已保存至 $clash_file,请下载使用!"
- fi
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- }
- function display_vmess_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local server_address
- local transport_type=$(jq -r '.inbounds[0].transport.type' "$config_file")
- local transport_path=$(jq -r '.inbounds[0].transport.path' "$config_file")
- local transport_service_name=$(jq -r '.inbounds[0].transport.service_name' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- if [[ -z "$domain" && -n "$domain_name" ]]; then
- server_address="$local_ip"
- elif [[ -z "$domain" && -z "$domain_name" ]]; then
- server_address="$local_ip"
- elif [[ -n "$domain" ]]; then
- server_address="$domain"
- fi
- echo -e "${CYAN}VMess 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $server_address" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "UUID列表:" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- for ((i=0; i<${#user_uuids[@]}; i++)); do
- user_uuid="${user_uuids[$i]}"
- echo "$user_uuid"| tee -a "$output_file"
- done
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- if [ "$transport_type" != "null" ]; then
- echo "传输协议: $transport_type" | tee -a "$output_file"
- if [ "$transport_type" == "ws" ]; then
- echo "路径: $transport_path" | tee -a "$output_file"
- elif [ "$transport_type" == "httpupgrade" ]; then
- echo "路径: $transport_path" | tee -a "$output_file"
- elif [ "$transport_type" == "grpc" ]; then
- echo "grpc-service-name: $transport_service_name" | tee -a "$output_file"
- fi
- else
- echo "传输协议: tcp" | tee -a "$output_file"
- fi
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_vmess_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local transport_type=$(jq -r '.inbounds[0].transport.type' "$config_file")
- local transport_path=$(jq -r '.inbounds[0].transport.path' "$config_file")
- local transport_service_name=$(jq -r '.inbounds[0].transport.service_name' "$config_file")
- local show_clash_message=true
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- for ((i=0; i<${#user_uuids[@]}; i++)); do
- user_uuid="${user_uuids[$i]}"
- write_phone_client_file
- write_win_client_file
- generate_vmess_win_client_config
- generate_vmess_phone_client_config
- if [ "$enable_ech" != true ] && [ -z "$domain" ] && [ -z "$domain_name" ] && [ "$transport_type" == "null" ]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vmess_tcp_yaml
- elif [ "$enable_ech" != true ] && [ -z "$domain" ] && [ -z "$domain_name" ] && [ "$transport_type" == "ws" ]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vmess_ws_yaml
- elif [ "$enable_ech" != true ] && [ -z "$domain" ] && [ -z "$domain_name" ] && [ "$transport_type" == "grpc" ]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vmess_grpc_yaml
- elif [ "$enable_ech" != true ] && [[ -n "$domain" || -n "$domain_name" ]] && [ "$transport_type" == "null" ]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vmess_tcp_tls_yaml
- elif [ "$enable_ech" != true ] && [[ -n "$domain" || -n "$domain_name" ]] && [ "$transport_type" == "ws" ]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vmess_ws_tls_yaml
- elif [ "$enable_ech" != true ] && [[ -n "$domain" || -n "$domain_name" ]] && [ "$transport_type" == "grpc" ]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_vmess_grpc_tls_yaml
- elif [ "$enable_ech" != true ] && [[ -n "$domain" || -n "$domain_name" ]] && [ "$transport_type" == "http" ]; then
- show_clash_message=false
- fi
- done
- if [ "$transport_type" == "http" ] || [ "$transport_type" == "httpupgrade" ] || [ "$enable_ech" = true ]; then
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- else
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- echo "Clash配置文件已保存至 $clash_file,请下载使用!"
- fi
- }
- function display_trojan_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local server_address
- local transport_type=$(jq -r '.inbounds[0].transport.type' "$config_file")
- local transport_path=$(jq -r '.inbounds[0].transport.path' "$config_file")
- local transport_service_name=$(jq -r '.inbounds[0].transport.service_name' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- if [[ -z "$domain" && -n "$domain_name" ]]; then
- server_address="$local_ip"
- elif [[ -z "$domain" && -z "$domain_name" ]]; then
- server_address="$local_ip"
- elif [[ -n "$domain" ]]; then
- server_address="$domain"
- fi
- echo -e "${CYAN}Trojan 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $server_address" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "密码列表:" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- for ((i = 0; i < ${#user_passwords[@]}; i++)); do
- user_password="${user_passwords[i]}"
- echo "$user_password"| tee -a "$output_file"
- done
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- if [ "$transport_type" != "null" ]; then
- echo "传输协议: $transport_type" | tee -a "$output_file"
- if [ "$transport_type" == "ws" ]; then
- echo "路径: $transport_path" | tee -a "$output_file"
- elif [ "$transport_type" == "httpupgrade" ]; then
- echo "路径: $transport_path" | tee -a "$output_file"
- elif [ "$transport_type" == "grpc" ]; then
- echo "grpc-service-name: $transport_service_name" | tee -a "$output_file"
- fi
- else
- echo "传输协议: tcp" | tee -a "$output_file"
- fi
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_trojan_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local transport_type=$(jq -r '.inbounds[0].transport.type' "$config_file")
- local transport_path=$(jq -r '.inbounds[0].transport.path' "$config_file")
- local transport_service_name=$(jq -r '.inbounds[0].transport.service_name' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- for ((i = 0; i < ${#user_passwords[@]}; i++)); do
- user_password="${user_passwords[i]}"
- write_phone_client_file
- write_win_client_file
- generate_trojan_win_client_config
- generate_trojan_phone_client_config
- if [[ "$enable_ech" != true ]] && [[ -n "$domain" || -n "$domain_name" ]] && [ "$transport_type" == "null" ]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_trojan_tcp_tls_yaml
- elif [[ "$enable_ech" != true ]] && [[ -n "$domain" || -n "$domain_name" ]] && [ "$transport_type" == "ws" ]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_trojan_ws_tls_yaml
- elif [[ "$enable_ech" != true ]] && [[ -n "$domain" || -n "$domain_name" ]] && [ "$transport_type" == "grpc" ]; then
- ensure_clash_yaml
- write_clash_yaml
- generate_trojan_grpc_tls_yaml
- fi
- done
- if [[ "$enable_ech" != true ]] && [[ -n "$domain" || -n "$domain_name" ]] && [[ "$transport_type" != "http" || "$transport_type" != "httpupgrade" ]]; then
- echo "Clash配置文件已保存至 $clash_file,请下载使用!"
- fi
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- }
- function display_shadowtls_config_info() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local output_file="/usr/local/etc/sing-box/output.txt"
- local user_input=$(jq -r '.inbounds[0].handshake.server' "$config_file")
- local method=$(jq -r '.inbounds[1].method' "$config_file")
- if [[ -n "$ip_v4" ]]; then
- local_ip="$ip_v4"
- elif [[ -n "$ip_v6" ]]; then
- local_ip="$ip_v6"
- fi
- echo -e "${CYAN}ShadowTLS 节点配置信息:${NC}" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "服务器地址: $local_ip" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "监听端口: $listen_port" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "加密方式: $method" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "ShadowTLS用户名 ShadowTLS密码" | tee -a "$output_file"
- echo "------------------------------------------------------------------------------" | tee -a "$output_file"
- for ((i = 0; i < ${#stls_passwords[@]}; i++)); do
- local stls_password="${stls_passwords[i]}"
- printf "%-25s %s\n" "$user_name" "$stls_password" | tee -a "$output_file"
- done
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "Shadowsocks 密码: $ss_passwords" | tee -a "$output_file"
- echo -e "${CYAN}------------------------------------------------------------------------------${NC}" | tee -a "$output_file"
- echo "握手服务器地址: $user_input" | tee -a "$output_file"
- echo -e "${CYAN}==============================================================================${NC}" | tee -a "$output_file"
- echo "" >> "$output_file"
- echo "配置信息已保存至 $output_file"
- }
- function display_shadowtls_config_files() {
- local config_file="/usr/local/etc/sing-box/config.json"
- local clash_file="/usr/local/etc/sing-box/clash.yaml"
- local phone_client_file="/usr/local/etc/sing-box/phone_client.json"
- local win_client_file="/usr/local/etc/sing-box/win_client.json"
- local user_input=$(jq -r '.inbounds[0].handshake.server' "$config_file")
- local method=$(jq -r '.inbounds[1].method' "$config_file")
- for ((i = 0; i < ${#stls_passwords[@]}; i++)); do
- local stls_password="${stls_passwords[i]}"
- write_phone_client_file
- write_win_client_file
- generate_shadowtls_win_client_config "$stls_password"
- generate_shadowtls_phone_client_config "$stls_password"
- ensure_clash_yaml
- write_clash_yaml
- generate_shadowtls_yaml
- done
- echo "手机端配置文件已保存至$phone_client_file,请下载后使用!"
- echo "电脑端配置文件已保存至$win_client_file,请下载后使用!"
- echo "Clash配置文件已保存至 $clash_file ,请下载使用!"
- }
- function view_saved_config() {
- local config_paths=(
- "/usr/local/etc/sing-box/output.txt"
- "/usr/local/etc/juicity/output.txt"
- )
- local found=false
- for path in "${config_paths[@]}"; do
- if [[ -f "$path" ]]; then
- echo "配置信息文件 ($path):"
- cat "$path"
- found=true
- fi
- done
- if [[ "$found" == false ]]; then
- echo "未找到保存的配置信息文件!"
- fi
- }
- function check_and_restart_services() {
- if [ -f "/etc/systemd/system/sing-box.service" ]; then
- systemctl restart sing-box.service
- systemctl status --no-pager sing-box.service
- fi
- if [ -f "/etc/systemd/system/juicity.service" ]; then
- systemctl restart juicity.service
- systemctl status --no-pager juicity.service
- fi
- }
- function uninstall_sing_box() {
- echo "开始卸载 sing-box..."
- systemctl stop sing-box
- systemctl disable sing-box
- rm -rf /usr/local/bin/sing-box
- rm -rf /usr/local/etc/sing-box
- rm -rf /etc/systemd/system/sing-box.service
- systemctl daemon-reload
- echo "sing-box 卸载完成。"
- }
- function uninstall_juicity() {
- echo "开始卸载 juicity..."
- systemctl stop juicity.service
- systemctl disable juicity.service
- rm -rf /etc/systemd/system/juicity.service
- rm -rf /usr/local/etc/juicity
- rm -rf /usr/local/bin/juicity-server
- echo "juicity 卸载完成。"
- }
- function update_proxy_tool() {
- if [ -e /usr/local/bin/juicity-server ]; then
- install_latest_juicity
- fi
- if [ -e /usr/local/bin/sing-box ]; then
- select_sing_box_install_option
- fi
- }
- function uninstall() {
- local uninstall_sing_box=false
- local uninstall_juicity=false
- if [[ -f "/etc/systemd/system/sing-box.service" ]] || [[ -f "/usr/local/bin/sing-box" ]] || [[ -d "/usr/local/etc/sing-box/" ]]; then
- uninstall_sing_box=true
- fi
- if [[ -f "/etc/systemd/system/juicity.service" ]] || [[ -f "/usr/local/bin/juicity-server" ]] || [[ -d "/usr/local/etc/juicity/" ]]; then
- uninstall_juicity=true
- fi
- if [[ "$uninstall_sing_box" == true ]]; then
- uninstall_sing_box
- fi
- if [[ "$uninstall_juicity" == true ]]; then
- uninstall_juicity
- fi
- }
- function check_wireguard_config() {
- local config_file="/usr/local/etc/sing-box/config.json"
- if grep -q "wireguard" "$config_file"; then
- echo -e "${RED}Warp 已安装,请勿重复安装!${NC}"
- exit 1
- fi
- }
- function Update_Script() {
- wget -O /root/singbox.sh https://raw.githubusercontent.com/qiuxiuya/qiuxiuya/main/VPS/singbox.sh
- chmod +x /root/singbox.sh
- }
- function add_cron_job() {
- if command -v crontab > /dev/null && crontab -l | grep -q "singbox.sh"; then
- echo "Cron job already exists."
- else
- (crontab -l 2>/dev/null ; echo "0 2 * * 1 /bin/bash /root/singbox.sh >> /usr/local/etc/certificate.log 2>&1") | crontab -
- echo "Cron job added successfully."
- fi
- }
- function juicity_install() {
- configure_dns64
- enable_bbr
- create_juicity_folder
- install_latest_juicity
- get_local_ip
- generate_juicity_config
- add_cron_job
- configure_juicity_service
- systemctl daemon-reload
- systemctl enable juicity.service
- systemctl start juicity.service
- systemctl restart juicity.service
- display_juicity_config
- }
- function Direct_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- set_listen_port
- set_override_address
- set_override_port
- generate_Direct_config
- modify_format_inbounds_and_outbounds
- modify_route_rules
- check_firewall_configuration
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- get_local_ip
- display_Direct_config
- }
- function Shadowsocks_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- set_listen_port
- select_encryption_method
- set_ss_password
- generate_ss_config
- modify_format_inbounds_and_outbounds
- modify_route_rules
- check_firewall_configuration
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- get_local_ip
- display_Shadowsocks_config_info
- display_Shadowsocks_config_files
- }
- function socks_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- generate_socks_config
- modify_format_inbounds_and_outbounds
- modify_route_rules
- check_firewall_configuration
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- get_local_ip
- display_socks_config_info
- display_socks_config_files
- }
- function NaiveProxy_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- generate_naive_config
- add_cron_job
- modify_format_inbounds_and_outbounds
- modify_route_rules
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- display_naive_config_info
- generate_naive_config_files
- }
- function http_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- generate_http_config
- add_cron_job
- modify_format_inbounds_and_outbounds
- modify_route_rules
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- display_http_config_info
- display_http_config_files
- }
- function tuic_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- generate_tuic_config
- add_cron_job
- modify_format_inbounds_and_outbounds
- modify_route_rules
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- get_local_ip
- display_tuic_config_info
- display_tuic_config_files
- }
- function Hysteria_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- generate_Hysteria_config
- add_cron_job
- modify_format_inbounds_and_outbounds
- modify_route_rules
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- display_Hysteria_config_info
- display_Hysteria_config_files
- }
- function shadowtls_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- generate_shadowtls_config
- modify_format_inbounds_and_outbounds
- modify_route_rules
- check_firewall_configuration
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- get_local_ip
- display_shadowtls_config_info
- display_shadowtls_config_files
- }
- function reality_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- generate_vless_config
- modify_format_inbounds_and_outbounds
- modify_route_rules
- check_firewall_configuration
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- get_local_ip
- display_reality_config_info
- display_reality_config_files
- }
- function Hysteria2_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- generate_Hy2_config
- add_cron_job
- modify_format_inbounds_and_outbounds
- modify_route_rules
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- display_Hy2_config_info
- display_Hy2_config_files
- }
- function trojan_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- generate_trojan_config
- add_cron_job
- modify_format_inbounds_and_outbounds
- modify_route_rules
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- display_trojan_config_info
- display_trojan_config_files
- }
- function vmess_install() {
- install_sing_box
- enable_bbr
- log_outbound_config
- get_local_ip
- generate_vmess_config
- add_cron_job
- modify_format_inbounds_and_outbounds
- modify_route_rules
- systemctl daemon-reload
- systemctl enable sing-box
- systemctl start sing-box
- systemctl restart sing-box
- display_vmess_config_info
- display_vmess_config_files
- }
- function wireguard_install() {
- check_wireguard_config
- check_config_file_existence
- select_unlocked_items
- geosite=()
- update_geosite_array
- select_outbound
- update_route_file "$outbound"
- get_temp_config_file
- extract_variables_and_cleanup
- update_outbound_file
- systemctl restart sing-box
- }
- function Update_certificate() {
- get_local_ip
- extract_tls_info
- validate_tls_info
- Reapply_certificates
- }
- function main_menu() {
- echo "╔════════════════════════════════════════════════════════════════════════╗"
- echo -e "║ ${CYAN}作者${NC}: Mr. xiao ║"
- echo -e "║ ${CYAN} Version:1.2 原作者已删库( ║"
- echo "╠════════════════════════════════════════════════════════════════════════╣"
- echo "║ 请选择要执行的操作: ║"
- echo -e "║${CYAN} [1]${NC} SOCKS ${CYAN} [2]${NC} Direct ║"
- echo -e "║${CYAN} [3]${NC} HTTP ${CYAN} [4]${NC} VMess ║"
- echo -e "║${CYAN} [5]${NC} VLESS ${CYAN} [6]${NC} TUIC ║"
- echo -e "║${CYAN} [7]${NC} Juicity ${CYAN} [8]${NC} Trojan ║"
- echo -e "║${CYAN} [9]${NC} Hysteria ${CYAN} [10]${NC} Hysteria2 ║"
- echo -e "║${CYAN} [11]${NC} ShadowTLS ${CYAN} [12]${NC} NaiveProxy ║"
- echo -e "║${CYAN} [13]${NC} Shadowsocks ${CYAN} [14]${NC} WireGuard ║"
- echo -e "║${CYAN} [15]${NC} 查看节点信息 ${CYAN} [16]${NC} 更新内核 ║"
- echo -e "║${CYAN} [17]${NC} 更新脚本 ${CYAN} [18]${NC} 更新证书 ║"
- echo -e "║${CYAN} [19]${NC} 重启服务 ${CYAN} [20]${NC} 节点管理 ║"
- echo -e "║${CYAN} [21]${NC} 卸载 ${CYAN} [0]${NC} 退出 ║"
- echo "╚════════════════════════════════════════════════════════════════════════╝"
- local choice
- read -p "请选择 [0-21]: " choice
- case $choice in
- 1)
- socks_install
- exit 0
- ;;
- 2)
- Direct_install
- exit 0
- ;;
- 3)
- http_install
- exit 0
- ;;
- 4)
- vmess_install
- exit 0
- ;;
- 5)
- reality_install
- exit 0
- ;;
- 6)
- tuic_install
- exit 0
- ;;
- 7)
- juicity_install
- exit 0
- ;;
- 8)
- trojan_install
- exit 0
- ;;
- 9)
- Hysteria_install
- exit 0
- ;;
- 10)
- Hysteria2_install
- exit 0
- ;;
- 11)
- shadowtls_install
- exit 0
- ;;
- 12)
- NaiveProxy_install
- exit 0
- ;;
- 13)
- Shadowsocks_install
- exit 0
- ;;
- 14)
- wireguard_install
- exit 0
- ;;
- 15)
- view_saved_config
- exit 0
- ;;
- 16)
- update_proxy_tool
- exit 0
- ;;
- 17)
- Update_Script
- exit 0
- ;;
- 18)
- Update_certificate
- ;;
- 19)
- check_and_restart_services
- exit 0
- ;;
- 20)
- delete_choice
- exit 0
- ;;
- 21)
- uninstall
- exit 0
- ;;
- 0)
- echo "感谢使用 Mr. xiao 安装脚本!再见!"
- exit 0
- ;;
- *)
- echo -e "${RED}无效的选择,请重新输入。${NC}"
- main_menu
- ;;
- esac
- }
- function run_option() {
- case "$1" in
- "18")
- Update_certificate
- exit 0
- ;;
- esac
- }
- if [ $# -eq 0 ]; then
- main_menu
- else
- run_option "$1"
- fi
- main_menu
|