xray-core_sing-box.sh 356 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538
  1. #!/usr/bin/env bash
  2. # 检测区
  3. # -------------------------------------------------------------
  4. # 检查系统
  5. export LANG=en_US.UTF-8
  6. echoContent() {
  7. case $1 in
  8. # 红色
  9. "red")
  10. # shellcheck disable=SC2154
  11. ${echoType} "\033[31m${printN}$2 \033[0m"
  12. ;;
  13. # 天蓝色
  14. "skyBlue")
  15. ${echoType} "\033[1;36m${printN}$2 \033[0m"
  16. ;;
  17. # 绿色
  18. "green")
  19. ${echoType} "\033[32m${printN}$2 \033[0m"
  20. ;;
  21. # 白色
  22. "white")
  23. ${echoType} "\033[37m${printN}$2 \033[0m"
  24. ;;
  25. "magenta")
  26. ${echoType} "\033[31m${printN}$2 \033[0m"
  27. ;;
  28. # 黄色
  29. "yellow")
  30. ${echoType} "\033[33m${printN}$2 \033[0m"
  31. ;;
  32. esac
  33. }
  34. # 检查SELinux状态
  35. checkCentosSELinux() {
  36. if [[ -f "/etc/selinux/config" ]] && ! grep -q "SELINUX=disabled" <"/etc/selinux/config"; then
  37. echoContent yellow "# 注意事项"
  38. echoContent yellow "检测到SELinux已开启,请手动关闭,教程如下"
  39. echoContent yellow "https://www.v2ray-agent.com/archives/1684115970026#centos7-%E5%85%B3%E9%97%ADselinux"
  40. exit 0
  41. fi
  42. }
  43. checkSystem() {
  44. if [[ -n $(find /etc -name "redhat-release") ]] || grep </proc/version -q -i "centos"; then
  45. mkdir -p /etc/yum.repos.d
  46. if [[ -f "/etc/centos-release" ]]; then
  47. centosVersion=$(rpm -q centos-release | awk -F "[-]" '{print $3}' | awk -F "[.]" '{print $1}')
  48. if [[ -z "${centosVersion}" ]] && grep </etc/centos-release -q -i "release 8"; then
  49. centosVersion=8
  50. fi
  51. fi
  52. release="centos"
  53. installType='yum -y install'
  54. removeType='yum -y remove'
  55. upgrade="yum update -y --skip-broken"
  56. checkCentosSELinux
  57. elif { [[ -f "/etc/issue" ]] && grep -qi "Alpine" /etc/issue; } || { [[ -f "/proc/version" ]] && grep -qi "Alpine" /proc/version; }; then
  58. release="alpine"
  59. installType='apk add'
  60. upgrade="apk update"
  61. removeType='apk del'
  62. nginxConfigPath=/etc/nginx/http.d/
  63. elif { [[ -f "/etc/issue" ]] && grep -qi "debian" /etc/issue; } || { [[ -f "/proc/version" ]] && grep -qi "debian" /proc/version; } || { [[ -f "/etc/os-release" ]] && grep -qi "ID=debian" /etc/issue; }; then
  64. release="debian"
  65. installType='apt -y install'
  66. upgrade="apt update"
  67. updateReleaseInfoChange='apt-get --allow-releaseinfo-change update'
  68. removeType='apt -y autoremove'
  69. elif { [[ -f "/etc/issue" ]] && grep -qi "ubuntu" /etc/issue; } || { [[ -f "/proc/version" ]] && grep -qi "ubuntu" /proc/version; }; then
  70. release="ubuntu"
  71. installType='apt -y install'
  72. upgrade="apt update"
  73. updateReleaseInfoChange='apt-get --allow-releaseinfo-change update'
  74. removeType='apt -y autoremove'
  75. if grep </etc/issue -q -i "16."; then
  76. release=
  77. fi
  78. fi
  79. if [[ -z ${release} ]]; then
  80. echoContent red "\n本脚本不支持此系统,请将下方日志反馈给开发者\n"
  81. echoContent yellow "$(cat /etc/issue)"
  82. echoContent yellow "$(cat /proc/version)"
  83. exit 0
  84. fi
  85. }
  86. # 检查CPU提供商
  87. checkCPUVendor() {
  88. if [[ -n $(which uname) ]]; then
  89. if [[ "$(uname)" == "Linux" ]]; then
  90. case "$(uname -m)" in
  91. 'amd64' | 'x86_64')
  92. xrayCoreCPUVendor="Xray-linux-64"
  93. # v2rayCoreCPUVendor="v2ray-linux-64"
  94. warpRegCoreCPUVendor="main-linux-amd64"
  95. singBoxCoreCPUVendor="-linux-amd64"
  96. ;;
  97. 'armv8' | 'aarch64')
  98. cpuVendor="arm"
  99. xrayCoreCPUVendor="Xray-linux-arm64-v8a"
  100. # v2rayCoreCPUVendor="v2ray-linux-arm64-v8a"
  101. warpRegCoreCPUVendor="main-linux-arm64"
  102. singBoxCoreCPUVendor="-linux-arm64"
  103. ;;
  104. *)
  105. echo " 不支持此CPU架构--->"
  106. exit 1
  107. ;;
  108. esac
  109. fi
  110. else
  111. echoContent red " 无法识别此CPU架构,默认amd64、x86_64--->"
  112. xrayCoreCPUVendor="Xray-linux-64"
  113. # v2rayCoreCPUVendor="v2ray-linux-64"
  114. fi
  115. }
  116. # 初始化全局变量
  117. initVar() {
  118. installType='yum -y install'
  119. removeType='yum -y remove'
  120. upgrade="yum -y update"
  121. echoType='echo -e'
  122. # 核心支持的cpu版本
  123. xrayCoreCPUVendor=""
  124. warpRegCoreCPUVendor=""
  125. cpuVendor=""
  126. # 域名
  127. domain=
  128. # 安装总进度
  129. totalProgress=1
  130. # 1.xray-core安装
  131. # 2.v2ray-core 安装
  132. # 3.v2ray-core[xtls] 安装
  133. coreInstallType=
  134. # 核心安装path
  135. # coreInstallPath=
  136. # v2ctl Path
  137. ctlPath=
  138. # 1.全部安装
  139. # 2.个性化安装
  140. # v2rayAgentInstallType=
  141. # 当前的个性化安装方式 01234
  142. currentInstallProtocolType=
  143. # 当前alpn的顺序
  144. currentAlpn=
  145. # 前置类型
  146. frontingType=
  147. # 选择的个性化安装方式
  148. selectCustomInstallType=
  149. # v2ray-core、xray-core配置文件的路径
  150. configPath=
  151. # xray-core reality状态
  152. realityStatus=
  153. # sing-box配置文件路径
  154. singBoxConfigPath=
  155. # sing-box端口
  156. singBoxVLESSVisionPort=
  157. singBoxVLESSRealityVisionPort=
  158. singBoxVLESSRealityGRPCPort=
  159. singBoxHysteria2Port=
  160. singBoxTrojanPort=
  161. singBoxTuicPort=
  162. singBoxNaivePort=
  163. singBoxVMessWSPort=
  164. singBoxVLESSWSPort=
  165. singBoxVMessHTTPUpgradePort=
  166. # nginx订阅端口
  167. subscribePort=
  168. subscribeType=
  169. # sing-box reality serverName publicKey
  170. singBoxVLESSRealityGRPCServerName=
  171. singBoxVLESSRealityVisionServerName=
  172. singBoxVLESSRealityPublicKey=
  173. # xray-core reality serverName publicKey
  174. xrayVLESSRealityServerName=
  175. xrayVLESSRealityPort=
  176. xrayVLESSRealityXHTTPServerName=
  177. xrayVLESSRealityXHTTPort=
  178. # xrayVLESSRealityPublicKey=
  179. # interfaceName=
  180. # 端口跳跃
  181. portHoppingStart=
  182. portHoppingEnd=
  183. portHopping=
  184. hysteria2PortHoppingStart=
  185. hysteria2PortHoppingEnd=
  186. hysteria2PortHopping=
  187. # tuicPortHoppingStart=
  188. # tuicPortHoppingEnd=
  189. # tuicPortHopping=
  190. # tuic配置文件路径
  191. # tuicConfigPath=
  192. tuicAlgorithm=
  193. tuicPort=
  194. # 配置文件的path
  195. currentPath=
  196. # 配置文件的host
  197. currentHost=
  198. # 安装时选择的core类型
  199. selectCoreType=
  200. # 默认core版本
  201. # v2rayCoreVersion=
  202. # 随机路径
  203. customPath=
  204. # centos version
  205. centosVersion=
  206. # UUID
  207. currentUUID=
  208. # clients
  209. currentClients=
  210. # previousClients
  211. # previousClients=
  212. localIP=
  213. # 定时任务执行任务名称 RenewTLS-更新证书 UpdateGeo-更新geo文件
  214. cronName=$1
  215. # tls安装失败后尝试的次数
  216. installTLSCount=
  217. # BTPanel状态
  218. # BTPanelStatus=
  219. # 宝塔域名
  220. btDomain=
  221. # nginx配置文件路径
  222. nginxConfigPath=/etc/nginx/conf.d/
  223. nginxStaticPath=/usr/share/nginx/html/
  224. # 是否为预览版
  225. prereleaseStatus=false
  226. # ssl类型
  227. sslType=
  228. # SSL CF API Token
  229. cfAPIToken=
  230. # ssl邮箱
  231. sslEmail=
  232. # 检查天数
  233. sslRenewalDays=90
  234. # dns ssl状态
  235. # dnsSSLStatus=
  236. # dns tls domain
  237. dnsTLSDomain=
  238. ipType=
  239. # 该域名是否通过dns安装通配符证书
  240. # installDNSACMEStatus=
  241. # 自定义端口
  242. customPort=
  243. # hysteria端口
  244. hysteriaPort=
  245. # hysteria协议
  246. # hysteriaProtocol=
  247. # hysteria延迟
  248. # hysteriaLag=
  249. # hysteria下行速度
  250. hysteria2ClientDownloadSpeed=
  251. # hysteria上行速度
  252. hysteria2ClientUploadSpeed=
  253. # Reality
  254. realityPrivateKey=
  255. realityServerName=
  256. realityDestDomain=
  257. # 端口状态
  258. # isPortOpen=
  259. # 通配符域名状态
  260. # wildcardDomainStatus=
  261. # 通过nginx检查的端口
  262. # nginxIPort=
  263. # wget show progress
  264. wgetShowProgressStatus=
  265. # warp
  266. reservedWarpReg=
  267. publicKeyWarpReg=
  268. addressWarpReg=
  269. secretKeyWarpReg=
  270. # 上次安装配置状态
  271. lastInstallationConfig=
  272. }
  273. # 读取tls证书详情
  274. readAcmeTLS() {
  275. local readAcmeDomain=
  276. if [[ -n "${currentHost}" ]]; then
  277. readAcmeDomain="${currentHost}"
  278. fi
  279. if [[ -n "${domain}" ]]; then
  280. readAcmeDomain="${domain}"
  281. fi
  282. dnsTLSDomain=$(echo "${readAcmeDomain}" | awk -F "." '{$1="";print $0}' | sed 's/^[[:space:]]*//' | sed 's/ /./g')
  283. if [[ -d "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc" && -f "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc/*.${dnsTLSDomain}.key" && -f "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc/*.${dnsTLSDomain}.cer" ]]; then
  284. installedDNSAPIStatus=true
  285. fi
  286. }
  287. # 读取默认自定义端口
  288. readCustomPort() {
  289. if [[ -n "${configPath}" && -z "${realityStatus}" && "${coreInstallType}" == "1" ]]; then
  290. local port=
  291. port=$(jq -r .inbounds[0].port "${configPath}${frontingType}.json")
  292. if [[ "${port}" != "443" ]]; then
  293. customPort=${port}
  294. fi
  295. fi
  296. }
  297. # 读取nginx订阅端口
  298. readNginxSubscribe() {
  299. subscribeType="https"
  300. if [[ -f "${nginxConfigPath}subscribe.conf" ]]; then
  301. if grep -q "sing-box" "${nginxConfigPath}subscribe.conf"; then
  302. subscribePort=$(grep "listen" "${nginxConfigPath}subscribe.conf" | awk '{print $2}')
  303. subscribeDomain=$(grep "server_name" "${nginxConfigPath}subscribe.conf" | awk '{print $2}')
  304. subscribeDomain=${subscribeDomain//;/}
  305. if [[ -n "${currentHost}" && "${subscribeDomain}" != "${currentHost}" ]]; then
  306. subscribePort=
  307. subscribeType=
  308. else
  309. if ! grep "listen" "${nginxConfigPath}subscribe.conf" | grep -q "ssl"; then
  310. subscribeType="http"
  311. fi
  312. fi
  313. fi
  314. fi
  315. }
  316. # 检测安装方式
  317. readInstallType() {
  318. coreInstallType=
  319. configPath=
  320. singBoxConfigPath=
  321. # 1.检测安装目录
  322. if [[ -d "/etc/v2ray-agent" ]]; then
  323. if [[ -f "/etc/v2ray-agent/xray/xray" ]]; then
  324. # 检测xray-core
  325. if [[ -d "/etc/v2ray-agent/xray/conf" ]] && [[ -f "/etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json" || -f "/etc/v2ray-agent/xray/conf/02_trojan_TCP_inbounds.json" || -f "/etc/v2ray-agent/xray/conf/07_VLESS_vision_reality_inbounds.json" ]]; then
  326. # xray-core
  327. configPath=/etc/v2ray-agent/xray/conf/
  328. ctlPath=/etc/v2ray-agent/xray/xray
  329. coreInstallType=1
  330. if [[ -f "${configPath}07_VLESS_vision_reality_inbounds.json" ]]; then
  331. realityStatus=1
  332. fi
  333. if [[ -f "/etc/v2ray-agent/sing-box/sing-box" ]] && [[ -f "/etc/v2ray-agent/sing-box/conf/config/06_hysteria2_inbounds.json" || -f "/etc/v2ray-agent/sing-box/conf/config/09_tuic_inbounds.json" || -f "/etc/v2ray-agent/sing-box/conf/config/20_socks5_inbounds.json" ]]; then
  334. singBoxConfigPath=/etc/v2ray-agent/sing-box/conf/config/
  335. fi
  336. fi
  337. elif [[ -f "/etc/v2ray-agent/sing-box/sing-box" && -f "/etc/v2ray-agent/sing-box/conf/config.json" ]]; then
  338. # 检测sing-box
  339. ctlPath=/etc/v2ray-agent/sing-box/sing-box
  340. coreInstallType=2
  341. configPath=/etc/v2ray-agent/sing-box/conf/config/
  342. singBoxConfigPath=/etc/v2ray-agent/sing-box/conf/config/
  343. fi
  344. fi
  345. }
  346. # 读取协议类型
  347. readInstallProtocolType() {
  348. currentInstallProtocolType=
  349. frontingType=
  350. xrayVLESSRealityPort=
  351. xrayVLESSRealityServerName=
  352. xrayVLESSRealityXHTTPort=
  353. xrayVLESSRealityXHTTPServerName=
  354. # currentRealityXHTTPPrivateKey=
  355. currentRealityXHTTPPublicKey=
  356. currentRealityPrivateKey=
  357. currentRealityPublicKey=
  358. currentRealityMldsa65Seed=
  359. currentRealityMldsa65Verify=
  360. singBoxVLESSVisionPort=
  361. singBoxHysteria2Port=
  362. singBoxTrojanPort=
  363. frontingTypeReality=
  364. singBoxVLESSRealityVisionPort=
  365. singBoxVLESSRealityVisionServerName=
  366. singBoxVLESSRealityGRPCPort=
  367. singBoxVLESSRealityGRPCServerName=
  368. singBoxAnyTLSPort=
  369. singBoxTuicPort=
  370. singBoxNaivePort=
  371. singBoxVMessWSPort=
  372. singBoxSocks5Port=
  373. while read -r row; do
  374. if echo "${row}" | grep -q VLESS_TCP_inbounds; then
  375. currentInstallProtocolType="${currentInstallProtocolType}0,"
  376. frontingType=02_VLESS_TCP_inbounds
  377. if [[ "${coreInstallType}" == "2" ]]; then
  378. singBoxVLESSVisionPort=$(jq .inbounds[0].listen_port "${row}.json")
  379. fi
  380. fi
  381. if echo "${row}" | grep -q VLESS_WS_inbounds; then
  382. currentInstallProtocolType="${currentInstallProtocolType}1,"
  383. if [[ "${coreInstallType}" == "2" ]]; then
  384. frontingType=03_VLESS_WS_inbounds
  385. singBoxVLESSWSPort=$(jq .inbounds[0].listen_port "${row}.json")
  386. fi
  387. fi
  388. if echo "${row}" | grep -q VLESS_XHTTP_inbounds; then
  389. currentInstallProtocolType="${currentInstallProtocolType}12,"
  390. xrayVLESSRealityXHTTPort=$(jq -r .inbounds[0].port "${row}.json")
  391. xrayVLESSRealityXHTTPServerName=$(jq -r .inbounds[0].streamSettings.realitySettings.serverNames[0] "${row}.json")
  392. currentRealityXHTTPPublicKey=$(jq -r .inbounds[0].streamSettings.realitySettings.publicKey "${row}.json")
  393. # currentRealityXHTTPPrivateKey=$(jq -r .inbounds[0].streamSettings.realitySettings.privateKey "${row}.json")
  394. # if [[ "${coreInstallType}" == "2" ]]; then
  395. # frontingType=03_VLESS_WS_inbounds
  396. # singBoxVLESSWSPort=$(jq .inbounds[0].listen_port "${row}.json")
  397. # fi
  398. fi
  399. if echo "${row}" | grep -q trojan_gRPC_inbounds; then
  400. currentInstallProtocolType="${currentInstallProtocolType}2,"
  401. fi
  402. if echo "${row}" | grep -q VMess_WS_inbounds; then
  403. currentInstallProtocolType="${currentInstallProtocolType}3,"
  404. if [[ "${coreInstallType}" == "2" ]]; then
  405. frontingType=05_VMess_WS_inbounds
  406. singBoxVMessWSPort=$(jq .inbounds[0].listen_port "${row}.json")
  407. fi
  408. fi
  409. if echo "${row}" | grep -q trojan_TCP_inbounds; then
  410. currentInstallProtocolType="${currentInstallProtocolType}4,"
  411. if [[ "${coreInstallType}" == "2" ]]; then
  412. frontingType=04_trojan_TCP_inbounds
  413. singBoxTrojanPort=$(jq .inbounds[0].listen_port "${row}.json")
  414. fi
  415. fi
  416. if echo "${row}" | grep -q VLESS_gRPC_inbounds; then
  417. currentInstallProtocolType="${currentInstallProtocolType}5,"
  418. fi
  419. if echo "${row}" | grep -q hysteria2_inbounds; then
  420. currentInstallProtocolType="${currentInstallProtocolType}6,"
  421. if [[ "${coreInstallType}" == "2" ]]; then
  422. frontingType=06_hysteria2_inbounds
  423. singBoxHysteria2Port=$(jq .inbounds[0].listen_port "${row}.json")
  424. fi
  425. fi
  426. if echo "${row}" | grep -q VLESS_vision_reality_inbounds; then
  427. currentInstallProtocolType="${currentInstallProtocolType}7,"
  428. if [[ "${coreInstallType}" == "1" ]]; then
  429. xrayVLESSRealityServerName=$(jq -r .inbounds[0].streamSettings.realitySettings.serverNames[0] "${row}.json")
  430. realityServerName=${xrayVLESSRealityServerName}
  431. xrayVLESSRealityPort=$(jq -r .inbounds[0].port "${row}.json")
  432. realityDomainPort=$(jq -r .inbounds[0].streamSettings.realitySettings.dest "${row}.json" | awk -F '[:]' '{print $2}')
  433. currentRealityPublicKey=$(jq -r .inbounds[0].streamSettings.realitySettings.publicKey "${row}.json")
  434. currentRealityPrivateKey=$(jq -r .inbounds[0].streamSettings.realitySettings.privateKey "${row}.json")
  435. currentRealityMldsa65Seed=$(jq -r .inbounds[0].streamSettings.realitySettings.mldsa65Seed "${row}.json")
  436. currentRealityMldsa65Verify=$(jq -r .inbounds[0].streamSettings.realitySettings.mldsa65Verify "${row}.json")
  437. frontingTypeReality=07_VLESS_vision_reality_inbounds
  438. elif [[ "${coreInstallType}" == "2" ]]; then
  439. frontingTypeReality=07_VLESS_vision_reality_inbounds
  440. singBoxVLESSRealityVisionPort=$(jq -r .inbounds[0].listen_port "${row}.json")
  441. singBoxVLESSRealityVisionServerName=$(jq -r .inbounds[0].tls.server_name "${row}.json")
  442. realityDomainPort=$(jq -r .inbounds[0].tls.reality.handshake.server_port "${row}.json")
  443. realityServerName=${singBoxVLESSRealityVisionServerName}
  444. if [[ -f "${configPath}reality_key" ]]; then
  445. singBoxVLESSRealityPublicKey=$(grep "publicKey" <"${configPath}reality_key" | awk -F "[:]" '{print $2}')
  446. currentRealityPrivateKey=$(jq -r .inbounds[0].tls.reality.private_key "${row}.json")
  447. currentRealityPublicKey=$(grep "publicKey" <"${configPath}reality_key" | awk -F "[:]" '{print $2}')
  448. fi
  449. fi
  450. fi
  451. if echo "${row}" | grep -q VLESS_vision_gRPC_inbounds; then
  452. currentInstallProtocolType="${currentInstallProtocolType}8,"
  453. if [[ "${coreInstallType}" == "2" ]]; then
  454. frontingTypeReality=08_VLESS_vision_gRPC_inbounds
  455. singBoxVLESSRealityGRPCPort=$(jq -r .inbounds[0].listen_port "${row}.json")
  456. singBoxVLESSRealityGRPCServerName=$(jq -r .inbounds[0].tls.server_name "${row}.json")
  457. if [[ -f "${configPath}reality_key" ]]; then
  458. singBoxVLESSRealityPublicKey=$(grep "publicKey" <"${configPath}reality_key" | awk -F "[:]" '{print $2}')
  459. fi
  460. fi
  461. fi
  462. if echo "${row}" | grep -q tuic_inbounds; then
  463. currentInstallProtocolType="${currentInstallProtocolType}9,"
  464. if [[ "${coreInstallType}" == "2" ]]; then
  465. frontingType=09_tuic_inbounds
  466. singBoxTuicPort=$(jq .inbounds[0].listen_port "${row}.json")
  467. fi
  468. fi
  469. if echo "${row}" | grep -q naive_inbounds; then
  470. currentInstallProtocolType="${currentInstallProtocolType}10,"
  471. if [[ "${coreInstallType}" == "2" ]]; then
  472. frontingType=10_naive_inbounds
  473. singBoxNaivePort=$(jq .inbounds[0].listen_port "${row}.json")
  474. fi
  475. fi
  476. if echo "${row}" | grep -q anytls_inbounds; then
  477. currentInstallProtocolType="${currentInstallProtocolType}13,"
  478. if [[ "${coreInstallType}" == "2" ]]; then
  479. frontingType=13_anytls_inbounds
  480. singBoxAnyTLSPort=$(jq .inbounds[0].listen_port "${row}.json")
  481. fi
  482. fi
  483. if echo "${row}" | grep -q VMess_HTTPUpgrade_inbounds; then
  484. currentInstallProtocolType="${currentInstallProtocolType}11,"
  485. if [[ "${coreInstallType}" == "2" ]]; then
  486. frontingType=11_VMess_HTTPUpgrade_inbounds
  487. singBoxVMessHTTPUpgradePort=$(grep 'listen' <${nginxConfigPath}sing_box_VMess_HTTPUpgrade.conf | awk '{print $2}')
  488. fi
  489. fi
  490. if echo "${row}" | grep -q socks5_inbounds; then
  491. currentInstallProtocolType="${currentInstallProtocolType}20,"
  492. singBoxSocks5Port=$(jq .inbounds[0].listen_port "${row}.json")
  493. fi
  494. done < <(find ${configPath} -name "*inbounds.json" | sort | awk -F "[.]" '{print $1}')
  495. if [[ "${coreInstallType}" == "1" && -n "${singBoxConfigPath}" ]]; then
  496. if [[ -f "${singBoxConfigPath}06_hysteria2_inbounds.json" ]]; then
  497. currentInstallProtocolType="${currentInstallProtocolType}6,"
  498. singBoxHysteria2Port=$(jq .inbounds[0].listen_port "${singBoxConfigPath}06_hysteria2_inbounds.json")
  499. fi
  500. if [[ -f "${singBoxConfigPath}09_tuic_inbounds.json" ]]; then
  501. currentInstallProtocolType="${currentInstallProtocolType}9,"
  502. singBoxTuicPort=$(jq .inbounds[0].listen_port "${singBoxConfigPath}09_tuic_inbounds.json")
  503. fi
  504. fi
  505. if [[ "${currentInstallProtocolType:0:1}" != "," ]]; then
  506. currentInstallProtocolType=",${currentInstallProtocolType}"
  507. fi
  508. }
  509. # 检查是否安装宝塔
  510. checkBTPanel() {
  511. if [[ -n $(pgrep -f "BT-Panel") ]]; then
  512. # 读取域名
  513. if [[ -d '/www/server/panel/vhost/cert/' && -n $(find /www/server/panel/vhost/cert/*/fullchain.pem) ]]; then
  514. if [[ -z "${currentHost}" ]]; then
  515. echoContent skyBlue "\n读取宝塔配置\n"
  516. find /www/server/panel/vhost/cert/*/fullchain.pem | awk -F "[/]" '{print $7}' | awk '{print NR""":"$0}'
  517. read -r -p "请输入编号选择:" selectBTDomain
  518. else
  519. selectBTDomain=$(find /www/server/panel/vhost/cert/*/fullchain.pem | awk -F "[/]" '{print $7}' | awk '{print NR""":"$0}' | grep "${currentHost}" | cut -d ":" -f 1)
  520. fi
  521. if [[ -n "${selectBTDomain}" ]]; then
  522. btDomain=$(find /www/server/panel/vhost/cert/*/fullchain.pem | awk -F "[/]" '{print $7}' | awk '{print NR""":"$0}' | grep -e "^${selectBTDomain}:" | cut -d ":" -f 2)
  523. if [[ -z "${btDomain}" ]]; then
  524. echoContent red " ---> 选择错误,请重新选择"
  525. checkBTPanel
  526. else
  527. domain=${btDomain}
  528. if [[ ! -f "/etc/v2ray-agent/tls/${btDomain}.crt" && ! -f "/etc/v2ray-agent/tls/${btDomain}.key" ]]; then
  529. ln -s "/www/server/panel/vhost/cert/${btDomain}/fullchain.pem" "/etc/v2ray-agent/tls/${btDomain}.crt"
  530. ln -s "/www/server/panel/vhost/cert/${btDomain}/privkey.pem" "/etc/v2ray-agent/tls/${btDomain}.key"
  531. fi
  532. nginxStaticPath="/www/wwwroot/${btDomain}/html/"
  533. mkdir -p "/www/wwwroot/${btDomain}/html/"
  534. if [[ -f "/www/wwwroot/${btDomain}/.user.ini" ]]; then
  535. chattr -i "/www/wwwroot/${btDomain}/.user.ini"
  536. fi
  537. nginxConfigPath="/www/server/panel/vhost/nginx/"
  538. fi
  539. else
  540. echoContent red " ---> 选择错误,请重新选择"
  541. checkBTPanel
  542. fi
  543. fi
  544. fi
  545. }
  546. check1Panel() {
  547. if [[ -n $(pgrep -f "1panel") ]]; then
  548. # 读取域名
  549. if [[ -d '/opt/1panel/apps/openresty/openresty/www/sites/' && -n $(find /opt/1panel/apps/openresty/openresty/www/sites/*/ssl/fullchain.pem) ]]; then
  550. if [[ -z "${currentHost}" ]]; then
  551. echoContent skyBlue "\n读取1Panel配置\n"
  552. find /opt/1panel/apps/openresty/openresty/www/sites/*/ssl/fullchain.pem | awk -F "[/]" '{print $9}' | awk '{print NR""":"$0}'
  553. read -r -p "请输入编号选择:" selectBTDomain
  554. else
  555. selectBTDomain=$(find /opt/1panel/apps/openresty/openresty/www/sites/*/ssl/fullchain.pem | awk -F "[/]" '{print $9}' | awk '{print NR""":"$0}' | grep "${currentHost}" | cut -d ":" -f 1)
  556. fi
  557. if [[ -n "${selectBTDomain}" ]]; then
  558. btDomain=$(find /opt/1panel/apps/openresty/openresty/www/sites/*/ssl/fullchain.pem | awk -F "[/]" '{print $9}' | awk '{print NR""":"$0}' | grep "${selectBTDomain}:" | cut -d ":" -f 2)
  559. if [[ -z "${btDomain}" ]]; then
  560. echoContent red " ---> 选择错误,请重新选择"
  561. check1Panel
  562. else
  563. domain=${btDomain}
  564. if [[ ! -f "/etc/v2ray-agent/tls/${btDomain}.crt" && ! -f "/etc/v2ray-agent/tls/${btDomain}.key" ]]; then
  565. ln -s "/opt/1panel/apps/openresty/openresty/www/sites/${btDomain}/ssl/fullchain.pem" "/etc/v2ray-agent/tls/${btDomain}.crt"
  566. ln -s "/opt/1panel/apps/openresty/openresty/www/sites/${btDomain}/ssl/privkey.pem" "/etc/v2ray-agent/tls/${btDomain}.key"
  567. fi
  568. nginxStaticPath="/opt/1panel/apps/openresty/openresty/www/sites/${btDomain}/index/"
  569. fi
  570. else
  571. echoContent red " ---> 选择错误,请重新选择"
  572. check1Panel
  573. fi
  574. fi
  575. fi
  576. }
  577. # 读取当前alpn的顺序
  578. readInstallAlpn() {
  579. if [[ -n "${currentInstallProtocolType}" && -z "${realityStatus}" ]]; then
  580. local alpn
  581. alpn=$(jq -r .inbounds[0].streamSettings.tlsSettings.alpn[0] ${configPath}${frontingType}.json)
  582. if [[ -n ${alpn} ]]; then
  583. currentAlpn=${alpn}
  584. fi
  585. fi
  586. }
  587. # 检查防火墙
  588. allowPort() {
  589. local type=$2
  590. if [[ -z "${type}" ]]; then
  591. type=tcp
  592. fi
  593. # 如果防火墙启动状态则添加相应的开放端口
  594. if dpkg -l | grep -q "^[[:space:]]*ii[[:space:]]\+ufw"; then
  595. if ufw status | grep -q "Status: active"; then
  596. if ! ufw status | grep -q "$1/${type}"; then
  597. sudo ufw allow "$1/${type}"
  598. checkUFWAllowPort "$1"
  599. fi
  600. fi
  601. elif systemctl status firewalld 2>/dev/null | grep -q "active (running)"; then
  602. local updateFirewalldStatus=
  603. if ! firewall-cmd --list-ports --permanent | grep -qw "$1/${type}"; then
  604. updateFirewalldStatus=true
  605. local firewallPort=$1
  606. if echo "${firewallPort}" | grep -q ":"; then
  607. firewallPort=$(echo "${firewallPort}" | awk -F ":" '{print $1"-"$2}')
  608. fi
  609. firewall-cmd --zone=public --add-port="${firewallPort}/${type}" --permanent
  610. checkFirewalldAllowPort "${firewallPort}"
  611. fi
  612. if echo "${updateFirewalldStatus}" | grep -q "true"; then
  613. firewall-cmd --reload
  614. fi
  615. elif rc-update show 2>/dev/null | grep -q ufw; then
  616. if ufw status | grep -q "Status: active"; then
  617. if ! ufw status | grep -q "$1/${type}"; then
  618. sudo ufw allow "$1/${type}"
  619. checkUFWAllowPort "$1"
  620. fi
  621. fi
  622. elif dpkg -l | grep -q "^[[:space:]]*ii[[:space:]]\+netfilter-persistent" && systemctl status netfilter-persistent 2>/dev/null | grep -q "active (exited)"; then
  623. local updateFirewalldStatus=
  624. if ! iptables -L | grep -q "$1/${type}(mack-a)"; then
  625. updateFirewalldStatus=true
  626. iptables -I INPUT -p ${type} --dport "$1" -m comment --comment "allow $1/${type}(mack-a)" -j ACCEPT
  627. fi
  628. if echo "${updateFirewalldStatus}" | grep -q "true"; then
  629. netfilter-persistent save
  630. fi
  631. fi
  632. }
  633. # 获取公网IP
  634. getPublicIP() {
  635. local type=4
  636. if [[ -n "$1" ]]; then
  637. type=$1
  638. fi
  639. if [[ -n "${currentHost}" && -z "$1" ]] && [[ "${singBoxVLESSRealityVisionServerName}" == "${currentHost}" || "${singBoxVLESSRealityGRPCServerName}" == "${currentHost}" || "${xrayVLESSRealityServerName}" == "${currentHost}" ]]; then
  640. echo "${currentHost}"
  641. else
  642. local currentIP=
  643. currentIP=$(curl -s "-${type}" http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | awk -F "[=]" '{print $2}')
  644. if [[ -z "${currentIP}" && -z "$1" ]]; then
  645. currentIP=$(curl -s "-6" http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | awk -F "[=]" '{print $2}')
  646. fi
  647. echo "${currentIP}"
  648. fi
  649. }
  650. # 输出ufw端口开放状态
  651. checkUFWAllowPort() {
  652. if ufw status | grep -q "$1"; then
  653. echoContent green " ---> $1端口开放成功"
  654. else
  655. echoContent red " ---> $1端口开放失败"
  656. exit 0
  657. fi
  658. }
  659. # 输出firewall-cmd端口开放状态
  660. checkFirewalldAllowPort() {
  661. if firewall-cmd --list-ports --permanent | grep -q "$1"; then
  662. echoContent green " ---> $1端口开放成功"
  663. else
  664. echoContent red " ---> $1端口开放失败"
  665. exit 0
  666. fi
  667. }
  668. # 读取Tuic配置
  669. readSingBoxConfig() {
  670. tuicPort=
  671. hysteriaPort=
  672. if [[ -n "${singBoxConfigPath}" ]]; then
  673. if [[ -f "${singBoxConfigPath}09_tuic_inbounds.json" ]]; then
  674. tuicPort=$(jq -r '.inbounds[0].listen_port' "${singBoxConfigPath}09_tuic_inbounds.json")
  675. tuicAlgorithm=$(jq -r '.inbounds[0].congestion_control' "${singBoxConfigPath}09_tuic_inbounds.json")
  676. fi
  677. if [[ -f "${singBoxConfigPath}06_hysteria2_inbounds.json" ]]; then
  678. hysteriaPort=$(jq -r '.inbounds[0].listen_port' "${singBoxConfigPath}06_hysteria2_inbounds.json")
  679. hysteria2ClientUploadSpeed=$(jq -r '.inbounds[0].down_mbps' "${singBoxConfigPath}06_hysteria2_inbounds.json")
  680. hysteria2ClientDownloadSpeed=$(jq -r '.inbounds[0].up_mbps' "${singBoxConfigPath}06_hysteria2_inbounds.json")
  681. fi
  682. fi
  683. }
  684. # 读取上次安装的配置
  685. readLastInstallationConfig() {
  686. if [[ -n "${configPath}" ]]; then
  687. read -r -p "读取到上次安装的配置,是否使用 ?[y/n]:" lastInstallationConfigStatus
  688. if [[ "${lastInstallationConfigStatus}" == "y" ]]; then
  689. lastInstallationConfig=true
  690. fi
  691. fi
  692. }
  693. # 卸载 sing-box
  694. unInstallSingBox() {
  695. local type=$1
  696. if [[ -n "${singBoxConfigPath}" ]]; then
  697. if grep -q 'tuic' </etc/v2ray-agent/sing-box/conf/config.json && [[ "${type}" == "tuic" ]]; then
  698. rm "${singBoxConfigPath}09_tuic_inbounds.json"
  699. echoContent green " ---> 删除sing-box tuic配置成功"
  700. fi
  701. if grep -q 'hysteria2' </etc/v2ray-agent/sing-box/conf/config.json && [[ "${type}" == "hysteria2" ]]; then
  702. rm "${singBoxConfigPath}06_hysteria2_inbounds.json"
  703. echoContent green " ---> 删除sing-box hysteria2配置成功"
  704. fi
  705. rm "${singBoxConfigPath}config.json"
  706. fi
  707. readInstallType
  708. if [[ -n "${singBoxConfigPath}" ]]; then
  709. echoContent yellow " ---> 检测到有其他配置,保留sing-box核心"
  710. handleSingBox stop
  711. handleSingBox start
  712. else
  713. handleSingBox stop
  714. rm /etc/systemd/system/sing-box.service
  715. rm -rf /etc/v2ray-agent/sing-box/*
  716. echoContent green " ---> sing-box 卸载完成"
  717. fi
  718. }
  719. # 检查文件目录以及path路径
  720. readConfigHostPathUUID() {
  721. currentPath=
  722. currentDefaultPort=
  723. currentUUID=
  724. currentClients=
  725. currentHost=
  726. currentPort=
  727. currentCDNAddress=
  728. singBoxVMessWSPath=
  729. singBoxVLESSWSPath=
  730. singBoxVMessHTTPUpgradePath=
  731. if [[ "${coreInstallType}" == "1" ]]; then
  732. # 安装
  733. if [[ -n "${frontingType}" ]]; then
  734. currentHost=$(jq -r .inbounds[0].streamSettings.tlsSettings.certificates[0].certificateFile ${configPath}${frontingType}.json | awk -F '[t][l][s][/]' '{print $2}' | awk -F '[.][c][r][t]' '{print $1}')
  735. currentPort=$(jq .inbounds[0].port ${configPath}${frontingType}.json)
  736. local defaultPortFile=
  737. defaultPortFile=$(find ${configPath}* | grep "default")
  738. if [[ -n "${defaultPortFile}" ]]; then
  739. currentDefaultPort=$(echo "${defaultPortFile}" | awk -F [_] '{print $4}')
  740. else
  741. currentDefaultPort=$(jq -r .inbounds[0].port ${configPath}${frontingType}.json)
  742. fi
  743. currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}${frontingType}.json)
  744. currentClients=$(jq -r .inbounds[0].settings.clients ${configPath}${frontingType}.json)
  745. fi
  746. # reality
  747. if echo ${currentInstallProtocolType} | grep -q ",7,"; then
  748. currentClients=$(jq -r .inbounds[0].settings.clients ${configPath}07_VLESS_vision_reality_inbounds.json)
  749. currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}07_VLESS_vision_reality_inbounds.json)
  750. xrayVLESSRealityVisionPort=$(jq -r .inbounds[0].port ${configPath}07_VLESS_vision_reality_inbounds.json)
  751. if [[ "${currentPort}" == "${xrayVLESSRealityVisionPort}" ]]; then
  752. xrayVLESSRealityVisionPort="${currentDefaultPort}"
  753. fi
  754. fi
  755. elif [[ "${coreInstallType}" == "2" ]]; then
  756. if [[ -n "${frontingType}" ]]; then
  757. currentHost=$(jq -r .inbounds[0].tls.server_name ${configPath}${frontingType}.json)
  758. if echo ${currentInstallProtocolType} | grep -q ",11," && [[ "${currentHost}" == "null" ]]; then
  759. currentHost=$(grep 'server_name' <${nginxConfigPath}sing_box_VMess_HTTPUpgrade.conf | awk '{print $2}')
  760. currentHost=${currentHost//;/}
  761. fi
  762. currentUUID=$(jq -r .inbounds[0].users[0].uuid ${configPath}${frontingType}.json)
  763. currentClients=$(jq -r .inbounds[0].users ${configPath}${frontingType}.json)
  764. else
  765. currentUUID=$(jq -r .inbounds[0].users[0].uuid ${configPath}${frontingTypeReality}.json)
  766. currentClients=$(jq -r .inbounds[0].users ${configPath}${frontingTypeReality}.json)
  767. fi
  768. fi
  769. # 读取path
  770. if [[ -n "${configPath}" && -n "${frontingType}" ]]; then
  771. if [[ "${coreInstallType}" == "1" ]]; then
  772. local fallback
  773. fallback=$(jq -r -c '.inbounds[0].settings.fallbacks[]|select(.path)' ${configPath}${frontingType}.json | head -1)
  774. local path
  775. path=$(echo "${fallback}" | jq -r .path | awk -F "[/]" '{print $2}')
  776. if [[ $(echo "${fallback}" | jq -r .dest) == 31297 ]]; then
  777. currentPath=$(echo "${path}" | awk -F "[w][s]" '{print $1}')
  778. elif [[ $(echo "${fallback}" | jq -r .dest) == 31299 ]]; then
  779. currentPath=$(echo "${path}" | awk -F "[v][w][s]" '{print $1}')
  780. fi
  781. # 尝试读取alpn h2 Path
  782. if [[ -z "${currentPath}" ]]; then
  783. dest=$(jq -r -c '.inbounds[0].settings.fallbacks[]|select(.alpn)|.dest' ${configPath}${frontingType}.json | head -1)
  784. if [[ "${dest}" == "31302" || "${dest}" == "31304" ]]; then
  785. checkBTPanel
  786. check1Panel
  787. if grep -q "trojangrpc {" <${nginxConfigPath}alone.conf; then
  788. currentPath=$(grep "trojangrpc {" <${nginxConfigPath}alone.conf | awk -F "[/]" '{print $2}' | awk -F "[t][r][o][j][a][n]" '{print $1}')
  789. elif grep -q "grpc {" <${nginxConfigPath}alone.conf; then
  790. currentPath=$(grep "grpc {" <${nginxConfigPath}alone.conf | head -1 | awk -F "[/]" '{print $2}' | awk -F "[g][r][p][c]" '{print $1}')
  791. fi
  792. fi
  793. fi
  794. if [[ -z "${currentPath}" && -f "${configPath}12_VLESS_XHTTP_inbounds.json" ]]; then
  795. currentPath=$(jq -r .inbounds[0].streamSettings.xhttpSettings.path "${configPath}12_VLESS_XHTTP_inbounds.json" | awk -F "[x][H][T][T][P]" '{print $1}' | awk -F "[/]" '{print $2}')
  796. fi
  797. elif [[ "${coreInstallType}" == "2" && -f "${singBoxConfigPath}05_VMess_WS_inbounds.json" ]]; then
  798. singBoxVMessWSPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}05_VMess_WS_inbounds.json")
  799. currentPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}05_VMess_WS_inbounds.json" | awk -F "[/]" '{print $2}')
  800. fi
  801. if [[ "${coreInstallType}" == "2" && -f "${singBoxConfigPath}03_VLESS_WS_inbounds.json" ]]; then
  802. singBoxVLESSWSPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}03_VLESS_WS_inbounds.json")
  803. currentPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}03_VLESS_WS_inbounds.json" | awk -F "[/]" '{print $2}')
  804. currentPath=${currentPath::-2}
  805. fi
  806. if [[ "${coreInstallType}" == "2" && -f "${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json" ]]; then
  807. singBoxVMessHTTPUpgradePath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json")
  808. currentPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json" | awk -F "[/]" '{print $2}')
  809. # currentPath=${currentPath::-2}
  810. fi
  811. fi
  812. if [[ -f "/etc/v2ray-agent/cdn" ]] && [[ -n "$(head -1 /etc/v2ray-agent/cdn)" ]]; then
  813. currentCDNAddress=$(head -1 /etc/v2ray-agent/cdn)
  814. else
  815. currentCDNAddress="${currentHost}"
  816. fi
  817. }
  818. # 状态展示
  819. showInstallStatus() {
  820. if [[ -n "${coreInstallType}" ]]; then
  821. if [[ "${coreInstallType}" == 1 ]]; then
  822. if [[ -n $(pgrep -f "xray/xray") ]]; then
  823. echoContent yellow "\n核心: Xray-core[运行中]"
  824. else
  825. echoContent yellow "\n核心: Xray-core[未运行]"
  826. fi
  827. elif [[ "${coreInstallType}" == 2 ]]; then
  828. if [[ -n $(pgrep -f "sing-box/sing-box") ]]; then
  829. echoContent yellow "\n核心: sing-box[运行中]"
  830. else
  831. echoContent yellow "\n核心: sing-box[未运行]"
  832. fi
  833. fi
  834. # 读取协议类型
  835. readInstallProtocolType
  836. if [[ -n ${currentInstallProtocolType} ]]; then
  837. echoContent yellow "已安装协议: \c"
  838. fi
  839. if echo ${currentInstallProtocolType} | grep -q ",0,"; then
  840. echoContent yellow "VLESS+TCP[TLS_Vision] \c"
  841. fi
  842. if echo ${currentInstallProtocolType} | grep -q ",1,"; then
  843. echoContent yellow "VLESS+WS[TLS] \c"
  844. fi
  845. if echo ${currentInstallProtocolType} | grep -q ",2,"; then
  846. echoContent yellow "Trojan+gRPC[TLS] \c"
  847. fi
  848. if echo ${currentInstallProtocolType} | grep -q ",3,"; then
  849. echoContent yellow "VMess+WS[TLS] \c"
  850. fi
  851. if echo ${currentInstallProtocolType} | grep -q ",4,"; then
  852. echoContent yellow "Trojan+TCP[TLS] \c"
  853. fi
  854. if echo ${currentInstallProtocolType} | grep -q ",5,"; then
  855. echoContent yellow "VLESS+gRPC[TLS] \c"
  856. fi
  857. if echo ${currentInstallProtocolType} | grep -q ",6,"; then
  858. echoContent yellow "Hysteria2 \c"
  859. fi
  860. if echo ${currentInstallProtocolType} | grep -q ",7,"; then
  861. echoContent yellow "VLESS+Reality+Vision \c"
  862. fi
  863. if echo ${currentInstallProtocolType} | grep -q ",8,"; then
  864. echoContent yellow "VLESS+Reality+gRPC \c"
  865. fi
  866. if echo ${currentInstallProtocolType} | grep -q ",9,"; then
  867. echoContent yellow "Tuic \c"
  868. fi
  869. if echo ${currentInstallProtocolType} | grep -q ",10,"; then
  870. echoContent yellow "Naive \c"
  871. fi
  872. if echo ${currentInstallProtocolType} | grep -q ",11,"; then
  873. echoContent yellow "VMess+TLS+HTTPUpgrade \c"
  874. fi
  875. if echo ${currentInstallProtocolType} | grep -q ",12,"; then
  876. echoContent yellow "VLESS+XHTTP \c"
  877. fi
  878. if echo ${currentInstallProtocolType} | grep -q ",13,"; then
  879. echoContent yellow "AnyTLS \c"
  880. fi
  881. fi
  882. }
  883. # 清理旧残留
  884. cleanUp() {
  885. if [[ "$1" == "xrayDel" ]]; then
  886. handleXray stop
  887. rm -rf /etc/v2ray-agent/xray/*
  888. elif [[ "$1" == "singBoxDel" ]]; then
  889. handleSingBox stop
  890. rm -rf /etc/v2ray-agent/sing-box/conf/config.json >/dev/null 2>&1
  891. rm -rf /etc/v2ray-agent/sing-box/conf/config/* >/dev/null 2>&1
  892. fi
  893. }
  894. initVar "$1"
  895. checkSystem
  896. checkCPUVendor
  897. readInstallType
  898. readInstallProtocolType
  899. readConfigHostPathUUID
  900. readCustomPort
  901. readSingBoxConfig
  902. # -------------------------------------------------------------
  903. # 初始化安装目录
  904. mkdirTools() {
  905. mkdir -p /etc/v2ray-agent/tls
  906. mkdir -p /etc/v2ray-agent/subscribe_local/default
  907. mkdir -p /etc/v2ray-agent/subscribe_local/clashMeta
  908. mkdir -p /etc/v2ray-agent/subscribe_remote/default
  909. mkdir -p /etc/v2ray-agent/subscribe_remote/clashMeta
  910. mkdir -p /etc/v2ray-agent/subscribe/default
  911. mkdir -p /etc/v2ray-agent/subscribe/clashMetaProfiles
  912. mkdir -p /etc/v2ray-agent/subscribe/clashMeta
  913. mkdir -p /etc/v2ray-agent/subscribe/sing-box
  914. mkdir -p /etc/v2ray-agent/subscribe/sing-box_profiles
  915. mkdir -p /etc/v2ray-agent/subscribe_local/sing-box
  916. mkdir -p /etc/v2ray-agent/xray/conf
  917. mkdir -p /etc/v2ray-agent/xray/reality_scan
  918. mkdir -p /etc/v2ray-agent/xray/tmp
  919. mkdir -p /etc/systemd/system/
  920. mkdir -p /tmp/v2ray-agent-tls/
  921. mkdir -p /etc/v2ray-agent/warp
  922. mkdir -p /etc/v2ray-agent/sing-box/conf/config
  923. mkdir -p /usr/share/nginx/html/
  924. }
  925. # 安装工具包
  926. installTools() {
  927. echoContent skyBlue "\n进度 $1/${totalProgress} : 安装工具"
  928. # 修复ubuntu个别系统问题
  929. if [[ "${release}" == "ubuntu" ]]; then
  930. dpkg --configure -a
  931. fi
  932. if [[ -n $(pgrep -f "apt") ]]; then
  933. pgrep -f apt | xargs kill -9
  934. fi
  935. echoContent green " ---> 检查、安装更新【新机器会很慢,如长时间无反应,请手动停止后重新执行】"
  936. ${upgrade} >/etc/v2ray-agent/install.log 2>&1
  937. if grep <"/etc/v2ray-agent/install.log" -q "changed"; then
  938. ${updateReleaseInfoChange} >/dev/null 2>&1
  939. fi
  940. if [[ "${release}" == "centos" ]]; then
  941. rm -rf /var/run/yum.pid
  942. ${installType} epel-release >/dev/null 2>&1
  943. fi
  944. if ! find /usr/bin /usr/sbin | grep -q -w sudo; then
  945. echoContent green " ---> 安装sudo"
  946. ${installType} sudo >/dev/null 2>&1
  947. fi
  948. if ! find /usr/bin /usr/sbin | grep -q -w wget; then
  949. echoContent green " ---> 安装wget"
  950. ${installType} wget >/dev/null 2>&1
  951. fi
  952. if ! find /usr/bin /usr/sbin | grep -q -w netfilter-persistent; then
  953. if [[ "${release}" != "centos" ]]; then
  954. echoContent green " ---> 安装iptables"
  955. echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | sudo debconf-set-selections
  956. echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | sudo debconf-set-selections
  957. ${installType} iptables-persistent >/dev/null 2>&1
  958. fi
  959. fi
  960. if ! find /usr/bin /usr/sbin | grep -q -w curl; then
  961. echoContent green " ---> 安装curl"
  962. ${installType} curl >/dev/null 2>&1
  963. fi
  964. if ! find /usr/bin /usr/sbin | grep -q -w unzip; then
  965. echoContent green " ---> 安装unzip"
  966. ${installType} unzip >/dev/null 2>&1
  967. fi
  968. if ! find /usr/bin /usr/sbin | grep -q -w socat; then
  969. echoContent green " ---> 安装socat"
  970. ${installType} socat >/dev/null 2>&1
  971. fi
  972. if ! find /usr/bin /usr/sbin | grep -q -w tar; then
  973. echoContent green " ---> 安装tar"
  974. ${installType} tar >/dev/null 2>&1
  975. fi
  976. if ! find /usr/bin /usr/sbin | grep -q -w cron; then
  977. echoContent green " ---> 安装crontabs"
  978. if [[ "${release}" == "ubuntu" ]] || [[ "${release}" == "debian" ]]; then
  979. ${installType} cron >/dev/null 2>&1
  980. else
  981. ${installType} crontabs >/dev/null 2>&1
  982. fi
  983. fi
  984. if ! find /usr/bin /usr/sbin | grep -q -w jq; then
  985. echoContent green " ---> 安装jq"
  986. ${installType} jq >/dev/null 2>&1
  987. fi
  988. if ! find /usr/bin /usr/sbin | grep -q -w binutils; then
  989. echoContent green " ---> 安装binutils"
  990. ${installType} binutils >/dev/null 2>&1
  991. fi
  992. if ! find /usr/bin /usr/sbin | grep -q -w openssl; then
  993. echoContent green " ---> 安装openssl"
  994. ${installType} openssl >/dev/null 2>&1
  995. fi
  996. if ! find /usr/bin /usr/sbin | grep -q -w ping6; then
  997. echoContent green " ---> 安装ping6"
  998. ${installType} inetutils-ping >/dev/null 2>&1
  999. fi
  1000. if ! find /usr/bin /usr/sbin | grep -q -w qrencode; then
  1001. echoContent green " ---> 安装qrencode"
  1002. ${installType} qrencode >/dev/null 2>&1
  1003. fi
  1004. if ! find /usr/bin /usr/sbin | grep -q -w lsb-release; then
  1005. echoContent green " ---> 安装lsb-release"
  1006. ${installType} lsb-release >/dev/null 2>&1
  1007. fi
  1008. if ! find /usr/bin /usr/sbin | grep -q -w lsof; then
  1009. echoContent green " ---> 安装lsof"
  1010. ${installType} lsof >/dev/null 2>&1
  1011. fi
  1012. if ! find /usr/bin /usr/sbin | grep -q -w dig; then
  1013. echoContent green " ---> 安装dig"
  1014. if echo "${installType}" | grep -qw "apt"; then
  1015. ${installType} dnsutils >/dev/null 2>&1
  1016. elif echo "${installType}" | grep -qw "yum"; then
  1017. ${installType} bind-utils >/dev/null 2>&1
  1018. elif echo "${installType}" | grep -qw "apk"; then
  1019. ${installType} bind-tools >/dev/null 2>&1
  1020. fi
  1021. fi
  1022. # 检测nginx版本,并提供是否卸载的选项
  1023. if echo "${selectCustomInstallType}" | grep -qwE ",7,|,8,|,7,8,"; then
  1024. echoContent green " ---> 检测到无需依赖Nginx的服务,跳过安装"
  1025. else
  1026. if ! find /usr/bin /usr/sbin | grep -q -w nginx; then
  1027. echoContent green " ---> 安装nginx"
  1028. installNginxTools
  1029. else
  1030. nginxVersion=$(nginx -v 2>&1)
  1031. nginxVersion=$(echo "${nginxVersion}" | awk -F "[n][g][i][n][x][/]" '{print $2}' | awk -F "[.]" '{print $2}')
  1032. if [[ ${nginxVersion} -lt 14 ]]; then
  1033. read -r -p "读取到当前的Nginx版本不支持gRPC,会导致安装失败,是否卸载Nginx后重新安装 ?[y/n]:" unInstallNginxStatus
  1034. if [[ "${unInstallNginxStatus}" == "y" ]]; then
  1035. ${removeType} nginx >/dev/null 2>&1
  1036. echoContent yellow " ---> nginx卸载完成"
  1037. echoContent green " ---> 安装nginx"
  1038. installNginxTools >/dev/null 2>&1
  1039. else
  1040. exit 0
  1041. fi
  1042. fi
  1043. fi
  1044. fi
  1045. if ! find /usr/bin /usr/sbin | grep -q -w semanage; then
  1046. echoContent green " ---> 安装semanage"
  1047. ${installType} bash-completion >/dev/null 2>&1
  1048. if [[ "${centosVersion}" == "7" ]]; then
  1049. policyCoreUtils="policycoreutils-python.x86_64"
  1050. elif [[ "${centosVersion}" == "8" ]]; then
  1051. policyCoreUtils="policycoreutils-python-utils-2.9-9.el8.noarch"
  1052. fi
  1053. if [[ -n "${policyCoreUtils}" ]]; then
  1054. ${installType} ${policyCoreUtils} >/dev/null 2>&1
  1055. fi
  1056. if [[ -n $(which semanage) ]]; then
  1057. semanage port -a -t http_port_t -p tcp 31300
  1058. fi
  1059. fi
  1060. if [[ "${selectCustomInstallType}" == "7" ]]; then
  1061. echoContent green " ---> 检测到无需依赖证书的服务,跳过安装"
  1062. else
  1063. if [[ ! -d "$HOME/.acme.sh" ]] || [[ -d "$HOME/.acme.sh" && -z $(find "$HOME/.acme.sh/acme.sh") ]]; then
  1064. echoContent green " ---> 安装acme.sh"
  1065. curl -s https://get.acme.sh | sh >/etc/v2ray-agent/tls/acme.log 2>&1
  1066. if [[ ! -d "$HOME/.acme.sh" ]] || [[ -z $(find "$HOME/.acme.sh/acme.sh") ]]; then
  1067. echoContent red " acme安装失败--->"
  1068. tail -n 100 /etc/v2ray-agent/tls/acme.log
  1069. echoContent yellow "错误排查:"
  1070. echoContent red " 1.获取Github文件失败,请等待Github恢复后尝试,恢复进度可查看 [https://www.githubstatus.com/]"
  1071. echoContent red " 2.acme.sh脚本出现bug,可查看[https://github.com/acmesh-official/acme.sh] issues"
  1072. echoContent red " 3.如纯IPv6机器,请设置NAT64,可执行下方命令,如果添加下方命令还是不可用,请尝试更换其他NAT64"
  1073. echoContent skyBlue " sed -i \"1i\\\nameserver 2a00:1098:2b::1\\\nnameserver 2a00:1098:2c::1\\\nnameserver 2a01:4f8:c2c:123f::1\\\nnameserver 2a01:4f9:c010:3f02::1\" /etc/resolv.conf"
  1074. exit 0
  1075. fi
  1076. fi
  1077. fi
  1078. }
  1079. # 开机启动
  1080. bootStartup() {
  1081. local serviceName=$1
  1082. if [[ "${release}" == "alpine" ]]; then
  1083. rc-update add "${serviceName}" default
  1084. else
  1085. systemctl daemon-reload
  1086. systemctl enable "${serviceName}"
  1087. fi
  1088. }
  1089. # 安装Nginx
  1090. installNginxTools() {
  1091. if [[ "${release}" == "debian" ]]; then
  1092. sudo apt install gnupg2 ca-certificates lsb-release -y >/dev/null 2>&1
  1093. echo "deb http://nginx.org/packages/mainline/debian $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list >/dev/null 2>&1
  1094. echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx >/dev/null 2>&1
  1095. curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key >/dev/null 2>&1
  1096. # gpg --dry-run --quiet --import --import-options import-show /tmp/nginx_signing.key
  1097. sudo mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc
  1098. sudo apt update >/dev/null 2>&1
  1099. elif [[ "${release}" == "ubuntu" ]]; then
  1100. sudo apt install gnupg2 ca-certificates lsb-release -y >/dev/null 2>&1
  1101. echo "deb http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list >/dev/null 2>&1
  1102. echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx >/dev/null 2>&1
  1103. curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key >/dev/null 2>&1
  1104. # gpg --dry-run --quiet --import --import-options import-show /tmp/nginx_signing.key
  1105. sudo mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc
  1106. sudo apt update >/dev/null 2>&1
  1107. elif [[ "${release}" == "centos" ]]; then
  1108. ${installType} yum-utils >/dev/null 2>&1
  1109. cat <<EOF >/etc/yum.repos.d/nginx.repo
  1110. [nginx-stable]
  1111. name=nginx stable repo
  1112. baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
  1113. gpgcheck=1
  1114. enabled=1
  1115. gpgkey=https://nginx.org/keys/nginx_signing.key
  1116. module_hotfixes=true
  1117. [nginx-mainline]
  1118. name=nginx mainline repo
  1119. baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/
  1120. gpgcheck=1
  1121. enabled=0
  1122. gpgkey=https://nginx.org/keys/nginx_signing.key
  1123. module_hotfixes=true
  1124. EOF
  1125. sudo yum-config-manager --enable nginx-mainline >/dev/null 2>&1
  1126. elif [[ "${release}" == "alpine" ]]; then
  1127. rm "${nginxConfigPath}default.conf"
  1128. fi
  1129. ${installType} nginx >/dev/null 2>&1
  1130. bootStartup nginx
  1131. }
  1132. # 安装warp
  1133. installWarp() {
  1134. if [[ "${cpuVendor}" == "arm" ]]; then
  1135. echoContent red " ---> 官方WARP客户端不支持ARM架构"
  1136. exit 0
  1137. fi
  1138. ${installType} gnupg2 -y >/dev/null 2>&1
  1139. if [[ "${release}" == "debian" ]]; then
  1140. curl -s https://pkg.cloudflareclient.com/pubkey.gpg | sudo apt-key add - >/dev/null 2>&1
  1141. echo "deb http://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list >/dev/null 2>&1
  1142. sudo apt update >/dev/null 2>&1
  1143. elif [[ "${release}" == "ubuntu" ]]; then
  1144. curl -s https://pkg.cloudflareclient.com/pubkey.gpg | sudo apt-key add - >/dev/null 2>&1
  1145. echo "deb http://pkg.cloudflareclient.com/ focal main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list >/dev/null 2>&1
  1146. sudo apt update >/dev/null 2>&1
  1147. elif [[ "${release}" == "centos" ]]; then
  1148. ${installType} yum-utils >/dev/null 2>&1
  1149. sudo rpm -ivh "http://pkg.cloudflareclient.com/cloudflare-release-el${centosVersion}.rpm" >/dev/null 2>&1
  1150. fi
  1151. echoContent green " ---> 安装WARP"
  1152. ${installType} cloudflare-warp >/dev/null 2>&1
  1153. if [[ -z $(which warp-cli) ]]; then
  1154. echoContent red " ---> 安装WARP失败"
  1155. exit 0
  1156. fi
  1157. systemctl enable warp-svc
  1158. warp-cli --accept-tos register
  1159. warp-cli --accept-tos set-mode proxy
  1160. warp-cli --accept-tos set-proxy-port 31303
  1161. warp-cli --accept-tos connect
  1162. warp-cli --accept-tos enable-always-on
  1163. local warpStatus=
  1164. warpStatus=$(curl -s --socks5 127.0.0.1:31303 https://www.cloudflare.com/cdn-cgi/trace | grep "warp" | cut -d "=" -f 2)
  1165. if [[ "${warpStatus}" == "on" ]]; then
  1166. echoContent green " ---> WARP启动成功"
  1167. fi
  1168. }
  1169. # 通过dns检查域名的IP
  1170. checkDNSIP() {
  1171. local domain=$1
  1172. local dnsIP=
  1173. ipType=4
  1174. dnsIP=$(dig @1.1.1.1 +time=2 +short "${domain}" | grep -E "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")
  1175. if [[ -z "${dnsIP}" ]]; then
  1176. dnsIP=$(dig @8.8.8.8 +time=2 +short "${domain}" | grep -E "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")
  1177. fi
  1178. if echo "${dnsIP}" | grep -q "timed out" || [[ -z "${dnsIP}" ]]; then
  1179. echo
  1180. echoContent red " ---> 无法通过DNS获取域名 IPv4 地址"
  1181. echoContent green " ---> 尝试检查域名 IPv6 地址"
  1182. dnsIP=$(dig @2606:4700:4700::1111 +time=2 aaaa +short "${domain}")
  1183. ipType=6
  1184. if echo "${dnsIP}" | grep -q "network unreachable" || [[ -z "${dnsIP}" ]]; then
  1185. echoContent red " ---> 无法通过DNS获取域名IPv6地址,退出安装"
  1186. exit 0
  1187. fi
  1188. fi
  1189. local publicIP=
  1190. publicIP=$(getPublicIP "${ipType}")
  1191. if [[ "${publicIP}" != "${dnsIP}" ]]; then
  1192. echoContent red " ---> 域名解析IP与当前服务器IP不一致\n"
  1193. echoContent yellow " ---> 请检查域名解析是否生效以及正确"
  1194. echoContent green " ---> 当前VPS IP:${publicIP}"
  1195. echoContent green " ---> DNS解析 IP:${dnsIP}"
  1196. exit 0
  1197. else
  1198. echoContent green " ---> 域名IP校验通过"
  1199. fi
  1200. }
  1201. # 检查端口实际开放状态
  1202. checkPortOpen() {
  1203. handleSingBox stop >/dev/null 2>&1
  1204. handleXray stop >/dev/null 2>&1
  1205. local port=$1
  1206. local domain=$2
  1207. local checkPortOpenResult=
  1208. allowPort "${port}"
  1209. if [[ -z "${btDomain}" ]]; then
  1210. handleNginx stop
  1211. # 初始化nginx配置
  1212. touch ${nginxConfigPath}checkPortOpen.conf
  1213. local listenIPv6PortConfig=
  1214. if [[ -n $(curl -s -6 -m 4 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2) ]]; then
  1215. listenIPv6PortConfig="listen [::]:${port};"
  1216. fi
  1217. cat <<EOF >${nginxConfigPath}checkPortOpen.conf
  1218. server {
  1219. listen ${port};
  1220. ${listenIPv6PortConfig}
  1221. server_name ${domain};
  1222. location /checkPort {
  1223. return 200 'fjkvymb6len';
  1224. }
  1225. location /ip {
  1226. proxy_set_header Host \$host;
  1227. proxy_set_header X-Real-IP \$remote_addr;
  1228. proxy_set_header REMOTE-HOST \$remote_addr;
  1229. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  1230. default_type text/plain;
  1231. return 200 \$proxy_add_x_forwarded_for;
  1232. }
  1233. }
  1234. EOF
  1235. handleNginx start
  1236. # 检查域名+端口的开放
  1237. checkPortOpenResult=$(curl -s -m 10 "http://${domain}:${port}/checkPort")
  1238. localIP=$(curl -s -m 10 "http://${domain}:${port}/ip")
  1239. rm "${nginxConfigPath}checkPortOpen.conf"
  1240. handleNginx stop
  1241. if [[ "${checkPortOpenResult}" == "fjkvymb6len" ]]; then
  1242. echoContent green " ---> 检测到${port}端口已开放"
  1243. else
  1244. echoContent green " ---> 未检测到${port}端口开放,退出安装"
  1245. if echo "${checkPortOpenResult}" | grep -q "cloudflare"; then
  1246. echoContent yellow " ---> 请关闭云朵后等待三分钟重新尝试"
  1247. else
  1248. if [[ -z "${checkPortOpenResult}" ]]; then
  1249. echoContent red " ---> 请检查是否有网页防火墙,比如Oracle等云服务商"
  1250. echoContent red " ---> 检查是否自己安装过nginx并且有配置冲突,可以尝试DD纯净系统后重新尝试"
  1251. else
  1252. echoContent red " ---> 错误日志:${checkPortOpenResult},请将此错误日志通过issues提交反馈"
  1253. fi
  1254. fi
  1255. exit 0
  1256. fi
  1257. checkIP "${localIP}"
  1258. fi
  1259. }
  1260. # 初始化Nginx申请证书配置
  1261. initTLSNginxConfig() {
  1262. handleNginx stop
  1263. echoContent skyBlue "\n进度 $1/${totalProgress} : 初始化Nginx申请证书配置"
  1264. if [[ -n "${currentHost}" && -z "${lastInstallationConfig}" ]]; then
  1265. echo
  1266. read -r -p "读取到上次安装记录,是否使用上次安装时的域名 ?[y/n]:" historyDomainStatus
  1267. if [[ "${historyDomainStatus}" == "y" ]]; then
  1268. domain=${currentHost}
  1269. echoContent yellow "\n ---> 域名: ${domain}"
  1270. else
  1271. echo
  1272. echoContent yellow "请输入要配置的域名 例: www.v2ray-agent.com --->"
  1273. read -r -p "域名:" domain
  1274. fi
  1275. elif [[ -n "${currentHost}" && -n "${lastInstallationConfig}" ]]; then
  1276. domain=${currentHost}
  1277. else
  1278. echo
  1279. echoContent yellow "请输入要配置的域名 例: www.v2ray-agent.com --->"
  1280. read -r -p "域名:" domain
  1281. fi
  1282. if [[ -z ${domain} ]]; then
  1283. echoContent red " 域名不可为空--->"
  1284. initTLSNginxConfig 3
  1285. else
  1286. dnsTLSDomain=$(echo "${domain}" | awk -F "." '{$1="";print $0}' | sed 's/^[[:space:]]*//' | sed 's/ /./g')
  1287. if [[ "${selectCoreType}" == "1" ]]; then
  1288. customPortFunction
  1289. fi
  1290. # 修改配置
  1291. handleNginx stop
  1292. fi
  1293. }
  1294. # 删除nginx默认的配置
  1295. removeNginxDefaultConf() {
  1296. if [[ -f ${nginxConfigPath}default.conf ]]; then
  1297. if [[ "$(grep -c "server_name" <${nginxConfigPath}default.conf)" == "1" ]] && [[ "$(grep -c "server_name localhost;" <${nginxConfigPath}default.conf)" == "1" ]]; then
  1298. echoContent green " ---> 删除Nginx默认配置"
  1299. rm -rf ${nginxConfigPath}default.conf >/dev/null 2>&1
  1300. fi
  1301. fi
  1302. }
  1303. # 修改nginx重定向配置
  1304. updateRedirectNginxConf() {
  1305. local redirectDomain=
  1306. redirectDomain=${domain}:${port}
  1307. local nginxH2Conf=
  1308. nginxH2Conf="listen 127.0.0.1:31302 http2 so_keepalive=on proxy_protocol;"
  1309. nginxVersion=$(nginx -v 2>&1)
  1310. if echo "${nginxVersion}" | grep -q "1.25" && [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $3}') -gt 0 ]] || [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $2}') -gt 25 ]]; then
  1311. nginxH2Conf="listen 127.0.0.1:31302 so_keepalive=on proxy_protocol;http2 on;"
  1312. fi
  1313. cat <<EOF >${nginxConfigPath}alone.conf
  1314. server {
  1315. listen 127.0.0.1:31300;
  1316. server_name _;
  1317. return 403;
  1318. }
  1319. EOF
  1320. if echo "${selectCustomInstallType}" | grep -qE ",2,|,5," || [[ -z "${selectCustomInstallType}" ]]; then
  1321. cat <<EOF >>${nginxConfigPath}alone.conf
  1322. server {
  1323. ${nginxH2Conf}
  1324. server_name ${domain};
  1325. root ${nginxStaticPath};
  1326. set_real_ip_from 127.0.0.1;
  1327. real_ip_header proxy_protocol;
  1328. client_header_timeout 1071906480m;
  1329. keepalive_timeout 1071906480m;
  1330. location /${currentPath}grpc {
  1331. if (\$content_type !~ "application/grpc") {
  1332. return 404;
  1333. }
  1334. client_max_body_size 0;
  1335. grpc_set_header X-Real-IP \$proxy_add_x_forwarded_for;
  1336. client_body_timeout 1071906480m;
  1337. grpc_read_timeout 1071906480m;
  1338. grpc_pass grpc://127.0.0.1:31301;
  1339. }
  1340. location /${currentPath}trojangrpc {
  1341. if (\$content_type !~ "application/grpc") {
  1342. return 404;
  1343. }
  1344. client_max_body_size 0;
  1345. grpc_set_header X-Real-IP \$proxy_add_x_forwarded_for;
  1346. client_body_timeout 1071906480m;
  1347. grpc_read_timeout 1071906480m;
  1348. grpc_pass grpc://127.0.0.1:31304;
  1349. }
  1350. location / {
  1351. }
  1352. }
  1353. EOF
  1354. elif echo "${selectCustomInstallType}" | grep -q ",5," || [[ -z "${selectCustomInstallType}" ]]; then
  1355. cat <<EOF >>${nginxConfigPath}alone.conf
  1356. server {
  1357. ${nginxH2Conf}
  1358. set_real_ip_from 127.0.0.1;
  1359. real_ip_header proxy_protocol;
  1360. server_name ${domain};
  1361. root ${nginxStaticPath};
  1362. location /${currentPath}grpc {
  1363. client_max_body_size 0;
  1364. keepalive_requests 4294967296;
  1365. client_body_timeout 1071906480m;
  1366. send_timeout 1071906480m;
  1367. lingering_close always;
  1368. grpc_read_timeout 1071906480m;
  1369. grpc_send_timeout 1071906480m;
  1370. grpc_pass grpc://127.0.0.1:31301;
  1371. }
  1372. location / {
  1373. }
  1374. }
  1375. EOF
  1376. elif echo "${selectCustomInstallType}" | grep -q ",2," || [[ -z "${selectCustomInstallType}" ]]; then
  1377. cat <<EOF >>${nginxConfigPath}alone.conf
  1378. server {
  1379. ${nginxH2Conf}
  1380. set_real_ip_from 127.0.0.1;
  1381. real_ip_header proxy_protocol;
  1382. server_name ${domain};
  1383. root ${nginxStaticPath};
  1384. location /${currentPath}trojangrpc {
  1385. client_max_body_size 0;
  1386. # keepalive_time 1071906480m;
  1387. keepalive_requests 4294967296;
  1388. client_body_timeout 1071906480m;
  1389. send_timeout 1071906480m;
  1390. lingering_close always;
  1391. grpc_read_timeout 1071906480m;
  1392. grpc_send_timeout 1071906480m;
  1393. grpc_pass grpc://127.0.0.1:31301;
  1394. }
  1395. location / {
  1396. }
  1397. }
  1398. EOF
  1399. else
  1400. cat <<EOF >>${nginxConfigPath}alone.conf
  1401. server {
  1402. ${nginxH2Conf}
  1403. set_real_ip_from 127.0.0.1;
  1404. real_ip_header proxy_protocol;
  1405. server_name ${domain};
  1406. root ${nginxStaticPath};
  1407. location / {
  1408. }
  1409. }
  1410. EOF
  1411. fi
  1412. cat <<EOF >>${nginxConfigPath}alone.conf
  1413. server {
  1414. listen 127.0.0.1:31300 proxy_protocol;
  1415. server_name ${domain};
  1416. set_real_ip_from 127.0.0.1;
  1417. real_ip_header proxy_protocol;
  1418. root ${nginxStaticPath};
  1419. location / {
  1420. }
  1421. }
  1422. EOF
  1423. handleNginx stop
  1424. }
  1425. # singbox Nginx config
  1426. singBoxNginxConfig() {
  1427. local type=$1
  1428. local port=$2
  1429. local nginxH2Conf=
  1430. nginxH2Conf="listen ${port} http2 so_keepalive=on ssl;"
  1431. nginxVersion=$(nginx -v 2>&1)
  1432. local singBoxNginxSSL=
  1433. singBoxNginxSSL="ssl_certificate /etc/v2ray-agent/tls/${domain}.crt;ssl_certificate_key /etc/v2ray-agent/tls/${domain}.key;"
  1434. if echo "${nginxVersion}" | grep -q "1.25" && [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $3}') -gt 0 ]] || [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $2}') -gt 25 ]]; then
  1435. nginxH2Conf="listen ${port} so_keepalive=on ssl;http2 on;"
  1436. fi
  1437. if echo "${selectCustomInstallType}" | grep -q ",11," || [[ "$1" == "all" ]]; then
  1438. cat <<EOF >>${nginxConfigPath}sing_box_VMess_HTTPUpgrade.conf
  1439. server {
  1440. ${nginxH2Conf}
  1441. server_name ${domain};
  1442. root ${nginxStaticPath};
  1443. ${singBoxNginxSSL}
  1444. ssl_protocols TLSv1.2 TLSv1.3;
  1445. ssl_ciphers TLS13_AES_128_GCM_SHA256:TLS13_AES_256_GCM_SHA384:TLS13_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;
  1446. ssl_prefer_server_ciphers on;
  1447. resolver 1.1.1.1 valid=60s;
  1448. resolver_timeout 2s;
  1449. client_max_body_size 100m;
  1450. location /${currentPath} {
  1451. if (\$http_upgrade != "websocket") {
  1452. return 444;
  1453. }
  1454. proxy_pass http://127.0.0.1:31306;
  1455. proxy_http_version 1.1;
  1456. proxy_set_header Upgrade \$http_upgrade;
  1457. proxy_set_header Connection "upgrade";
  1458. proxy_set_header X-Real-IP \$remote_addr;
  1459. proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
  1460. proxy_set_header Host \$host;
  1461. proxy_redirect off;
  1462. }
  1463. }
  1464. EOF
  1465. fi
  1466. }
  1467. # 检查ip
  1468. checkIP() {
  1469. echoContent skyBlue "\n ---> 检查域名ip中"
  1470. local localIP=$1
  1471. if [[ -z ${localIP} ]] || ! echo "${localIP}" | sed '1{s/[^(]*(//;s/).*//;q}' | grep -q '\.' && ! echo "${localIP}" | sed '1{s/[^(]*(//;s/).*//;q}' | grep -q ':'; then
  1472. echoContent red "\n ---> 未检测到当前域名的ip"
  1473. echoContent skyBlue " ---> 请依次进行下列检查"
  1474. echoContent yellow " ---> 1.检查域名是否书写正确"
  1475. echoContent yellow " ---> 2.检查域名dns解析是否正确"
  1476. echoContent yellow " ---> 3.如解析正确,请等待dns生效,预计三分钟内生效"
  1477. echoContent yellow " ---> 4.如报Nginx启动问题,请手动启动nginx查看错误,如自己无法处理请提issues"
  1478. echo
  1479. echoContent skyBlue " ---> 如以上设置都正确,请重新安装纯净系统后再次尝试"
  1480. if [[ -n ${localIP} ]]; then
  1481. echoContent yellow " ---> 检测返回值异常,建议手动卸载nginx后重新执行脚本"
  1482. echoContent red " ---> 异常结果:${localIP}"
  1483. fi
  1484. exit 0
  1485. else
  1486. if echo "${localIP}" | awk -F "[,]" '{print $2}' | grep -q "." || echo "${localIP}" | awk -F "[,]" '{print $2}' | grep -q ":"; then
  1487. echoContent red "\n ---> 检测到多个ip,请确认是否关闭cloudflare的云朵"
  1488. echoContent yellow " ---> 关闭云朵后等待三分钟后重试"
  1489. echoContent yellow " ---> 检测到的ip如下:[${localIP}]"
  1490. exit 0
  1491. fi
  1492. echoContent green " ---> 检查当前域名IP正确"
  1493. fi
  1494. }
  1495. # 自定义email
  1496. customSSLEmail() {
  1497. if echo "$1" | grep -q "validate email"; then
  1498. read -r -p "是否重新输入邮箱地址[y/n]:" sslEmailStatus
  1499. if [[ "${sslEmailStatus}" == "y" ]]; then
  1500. sed '/ACCOUNT_EMAIL/d' /root/.acme.sh/account.conf >/root/.acme.sh/account.conf_tmp && mv /root/.acme.sh/account.conf_tmp /root/.acme.sh/account.conf
  1501. else
  1502. exit 0
  1503. fi
  1504. fi
  1505. if [[ -d "/root/.acme.sh" && -f "/root/.acme.sh/account.conf" ]]; then
  1506. if ! grep -q "ACCOUNT_EMAIL" <"/root/.acme.sh/account.conf" && ! echo "${sslType}" | grep -q "letsencrypt"; then
  1507. read -r -p "请输入邮箱地址:" sslEmail
  1508. if echo "${sslEmail}" | grep -q "@"; then
  1509. echo "ACCOUNT_EMAIL='${sslEmail}'" >>/root/.acme.sh/account.conf
  1510. echoContent green " ---> 添加完毕"
  1511. else
  1512. echoContent yellow "请重新输入正确的邮箱格式[例: username@example.com]"
  1513. customSSLEmail
  1514. fi
  1515. fi
  1516. fi
  1517. }
  1518. # DNS API申请证书
  1519. switchDNSAPI() {
  1520. read -r -p "是否使用DNS API申请证书[支持NAT]?[y/n]:" dnsAPIStatus
  1521. if [[ "${dnsAPIStatus}" == "y" ]]; then
  1522. echoContent red "\n=============================================================="
  1523. echoContent yellow "1.cloudflare[默认]"
  1524. echoContent yellow "2.aliyun"
  1525. echoContent red "=============================================================="
  1526. read -r -p "请选择[回车]使用默认:" selectDNSAPIType
  1527. case ${selectDNSAPIType} in
  1528. 1)
  1529. dnsAPIType="cloudflare"
  1530. ;;
  1531. 2)
  1532. dnsAPIType="aliyun"
  1533. ;;
  1534. *)
  1535. dnsAPIType="cloudflare"
  1536. ;;
  1537. esac
  1538. initDNSAPIConfig "${dnsAPIType}"
  1539. fi
  1540. }
  1541. # 初始化dns配置
  1542. initDNSAPIConfig() {
  1543. if [[ "$1" == "cloudflare" ]]; then
  1544. echoContent yellow "\n CF_Token参考配置教程:https://www.v2ray-agent.com/archives/1701160377972\n"
  1545. read -r -p "请输入API Token:" cfAPIToken
  1546. if [[ -z "${cfAPIToken}" ]]; then
  1547. echoContent red " ---> 输入为空,请重新输入"
  1548. initDNSAPIConfig "$1"
  1549. else
  1550. echo
  1551. if ! echo "${dnsTLSDomain}" | grep -q "\." || [[ -z $(echo "${dnsTLSDomain}" | awk -F "[.]" '{print $1}') ]]; then
  1552. echoContent green " ---> 不支持此域名申请通配符证书,建议使用此格式[xx.xx.xx]"
  1553. exit 0
  1554. fi
  1555. read -r -p "是否使用*.${dnsTLSDomain}进行API申请通配符证书?[y/n]:" dnsAPIStatus
  1556. fi
  1557. elif [[ "$1" == "aliyun" ]]; then
  1558. read -r -p "请输入Ali Key:" aliKey
  1559. read -r -p "请输入Ali Secret:" aliSecret
  1560. if [[ -z "${aliKey}" || -z "${aliSecret}" ]]; then
  1561. echoContent red " ---> 输入为空,请重新输入"
  1562. initDNSAPIConfig "$1"
  1563. else
  1564. echo
  1565. if ! echo "${dnsTLSDomain}" | grep -q "\." || [[ -z $(echo "${dnsTLSDomain}" | awk -F "[.]" '{print $1}') ]]; then
  1566. echoContent green " ---> 不支持此域名申请通配符证书,建议使用此格式[xx.xx.xx]"
  1567. exit 0
  1568. fi
  1569. read -r -p "是否使用*.${dnsTLSDomain}进行API申请通配符证书?[y/n]:" dnsAPIStatus
  1570. fi
  1571. fi
  1572. }
  1573. # 选择ssl安装类型
  1574. switchSSLType() {
  1575. if [[ -z "${sslType}" ]]; then
  1576. echoContent red "\n=============================================================="
  1577. echoContent yellow "1.letsencrypt[默认]"
  1578. echoContent yellow "2.zerossl"
  1579. echoContent yellow "3.buypass[不支持DNS申请]"
  1580. echoContent red "=============================================================="
  1581. read -r -p "请选择[回车]使用默认:" selectSSLType
  1582. case ${selectSSLType} in
  1583. 1)
  1584. sslType="letsencrypt"
  1585. ;;
  1586. 2)
  1587. sslType="zerossl"
  1588. ;;
  1589. 3)
  1590. sslType="buypass"
  1591. ;;
  1592. *)
  1593. sslType="letsencrypt"
  1594. ;;
  1595. esac
  1596. if [[ -n "${dnsAPIType}" && "${sslType}" == "buypass" ]]; then
  1597. echoContent red " ---> buypass不支持API申请证书"
  1598. exit 0
  1599. fi
  1600. echo "${sslType}" >/etc/v2ray-agent/tls/ssl_type
  1601. fi
  1602. }
  1603. # 选择acme安装证书方式
  1604. selectAcmeInstallSSL() {
  1605. # local sslIPv6=
  1606. # local currentIPType=
  1607. if [[ "${ipType}" == "6" ]]; then
  1608. sslIPv6="--listen-v6"
  1609. fi
  1610. # currentIPType=$(curl -s "-${ipType}" http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2)
  1611. # if [[ -z "${currentIPType}" ]]; then
  1612. # currentIPType=$(curl -s -6 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2)
  1613. # if [[ -n "${currentIPType}" ]]; then
  1614. # sslIPv6="--listen-v6"
  1615. # fi
  1616. # fi
  1617. acmeInstallSSL
  1618. readAcmeTLS
  1619. }
  1620. # 安装SSL证书
  1621. acmeInstallSSL() {
  1622. local dnsAPIDomain="${tlsDomain}"
  1623. if [[ "${dnsAPIStatus}" == "y" ]]; then
  1624. dnsAPIDomain="*.${dnsTLSDomain}"
  1625. fi
  1626. if [[ "${dnsAPIType}" == "cloudflare" ]]; then
  1627. echoContent green " ---> DNS API 生成证书中"
  1628. sudo CF_Token="${cfAPIToken}" "$HOME/.acme.sh/acme.sh" --issue -d "${dnsAPIDomain}" -d "${dnsTLSDomain}" --dns dns_cf -k ec-256 --server "${sslType}" ${sslIPv6} 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null
  1629. elif [[ "${dnsAPIType}" == "aliyun" ]]; then
  1630. echoContent green " ---> DNS API 生成证书中"
  1631. sudo Ali_Key="${aliKey}" Ali_Secret="${aliSecret}" "$HOME/.acme.sh/acme.sh" --issue -d "${dnsAPIDomain}" -d "${dnsTLSDomain}" --dns dns_ali -k ec-256 --server "${sslType}" ${sslIPv6} 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null
  1632. else
  1633. echoContent green " ---> 生成证书中"
  1634. sudo "$HOME/.acme.sh/acme.sh" --issue -d "${tlsDomain}" --standalone -k ec-256 --server "${sslType}" ${sslIPv6} 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null
  1635. fi
  1636. }
  1637. # 自定义端口
  1638. customPortFunction() {
  1639. local historyCustomPortStatus=
  1640. if [[ -n "${customPort}" || -n "${currentPort}" ]]; then
  1641. echo
  1642. if [[ -z "${lastInstallationConfig}" ]]; then
  1643. read -r -p "读取到上次安装时的端口,是否使用上次安装时的端口?[y/n]:" historyCustomPortStatus
  1644. if [[ "${historyCustomPortStatus}" == "y" ]]; then
  1645. port=${currentPort}
  1646. echoContent yellow "\n ---> 端口: ${port}"
  1647. fi
  1648. elif [[ -n "${lastInstallationConfig}" ]]; then
  1649. port=${currentPort}
  1650. fi
  1651. fi
  1652. if [[ -z "${currentPort}" ]] || [[ "${historyCustomPortStatus}" == "n" ]]; then
  1653. echo
  1654. if [[ -n "${btDomain}" ]]; then
  1655. echoContent yellow "请输入端口[不可与BT Panel/1Panel端口相同,回车随机]"
  1656. read -r -p "端口:" port
  1657. if [[ -z "${port}" ]]; then
  1658. port=$((RANDOM % 20001 + 10000))
  1659. fi
  1660. else
  1661. echo
  1662. echoContent yellow "请输入端口[默认: 443],可自定义端口[回车使用默认]"
  1663. read -r -p "端口:" port
  1664. if [[ -z "${port}" ]]; then
  1665. port=443
  1666. fi
  1667. if [[ "${port}" == "${xrayVLESSRealityPort}" ]]; then
  1668. handleXray stop
  1669. fi
  1670. fi
  1671. if [[ -n "${port}" ]]; then
  1672. if ((port >= 1 && port <= 65535)); then
  1673. allowPort "${port}"
  1674. echoContent yellow "\n ---> 端口: ${port}"
  1675. if [[ -z "${btDomain}" ]]; then
  1676. checkDNSIP "${domain}"
  1677. removeNginxDefaultConf
  1678. checkPortOpen "${port}" "${domain}"
  1679. fi
  1680. else
  1681. echoContent red " ---> 端口输入错误"
  1682. exit 0
  1683. fi
  1684. else
  1685. echoContent red " ---> 端口不可为空"
  1686. exit 0
  1687. fi
  1688. fi
  1689. }
  1690. # 检测端口是否占用
  1691. checkPort() {
  1692. if [[ -n "$1" ]] && lsof -i "tcp:$1" | grep -q LISTEN; then
  1693. echoContent red "\n ---> $1端口被占用,请手动关闭后安装\n"
  1694. lsof -i "tcp:$1" | grep LISTEN
  1695. exit 0
  1696. fi
  1697. }
  1698. # 安装TLS
  1699. installTLS() {
  1700. echoContent skyBlue "\n进度 $1/${totalProgress} : 申请TLS证书\n"
  1701. readAcmeTLS
  1702. local tlsDomain=${domain}
  1703. # 安装tls
  1704. if [[ -f "/etc/v2ray-agent/tls/${tlsDomain}.crt" && -f "/etc/v2ray-agent/tls/${tlsDomain}.key" && -n $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]] || [[ -d "$HOME/.acme.sh/${tlsDomain}_ecc" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.key" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.cer" ]] || [[ "${installedDNSAPIStatus}" == "true" ]]; then
  1705. echoContent green " ---> 检测到证书"
  1706. renewalTLS
  1707. if [[ -z $(find /etc/v2ray-agent/tls/ -name "${tlsDomain}.crt") ]] || [[ -z $(find /etc/v2ray-agent/tls/ -name "${tlsDomain}.key") ]] || [[ -z $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]]; then
  1708. if [[ "${installedDNSAPIStatus}" == "true" ]]; then
  1709. sudo "$HOME/.acme.sh/acme.sh" --installcert -d "*.${dnsTLSDomain}" --fullchainpath "/etc/v2ray-agent/tls/${tlsDomain}.crt" --keypath "/etc/v2ray-agent/tls/${tlsDomain}.key" --ecc >/dev/null
  1710. else
  1711. sudo "$HOME/.acme.sh/acme.sh" --installcert -d "${tlsDomain}" --fullchainpath "/etc/v2ray-agent/tls/${tlsDomain}.crt" --keypath "/etc/v2ray-agent/tls/${tlsDomain}.key" --ecc >/dev/null
  1712. fi
  1713. else
  1714. if [[ -d "$HOME/.acme.sh/${tlsDomain}_ecc" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.key" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.cer" ]] || [[ "${installedDNSAPIStatus}" == "true" ]]; then
  1715. if [[ -z "${lastInstallationConfig}" ]]; then
  1716. echoContent yellow " ---> 如未过期或者自定义证书请选择[n]\n"
  1717. read -r -p "是否重新安装?[y/n]:" reInstallStatus
  1718. if [[ "${reInstallStatus}" == "y" ]]; then
  1719. rm -rf /etc/v2ray-agent/tls/*
  1720. installTLS "$1"
  1721. fi
  1722. fi
  1723. fi
  1724. fi
  1725. elif [[ -d "$HOME/.acme.sh" ]] && [[ ! -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.cer" || ! -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.key" ]]; then
  1726. switchDNSAPI
  1727. if [[ -z "${dnsAPIType}" ]]; then
  1728. echoContent yellow "\n ---> 不采用API申请证书"
  1729. echoContent green " ---> 安装TLS证书,需要依赖80端口"
  1730. allowPort 80
  1731. fi
  1732. switchSSLType
  1733. customSSLEmail
  1734. selectAcmeInstallSSL
  1735. if [[ "${installedDNSAPIStatus}" == "true" ]]; then
  1736. sudo "$HOME/.acme.sh/acme.sh" --installcert -d "*.${dnsTLSDomain}" --fullchainpath "/etc/v2ray-agent/tls/${tlsDomain}.crt" --keypath "/etc/v2ray-agent/tls/${tlsDomain}.key" --ecc >/dev/null
  1737. else
  1738. sudo "$HOME/.acme.sh/acme.sh" --installcert -d "${tlsDomain}" --fullchainpath "/etc/v2ray-agent/tls/${tlsDomain}.crt" --keypath "/etc/v2ray-agent/tls/${tlsDomain}.key" --ecc >/dev/null
  1739. fi
  1740. if [[ ! -f "/etc/v2ray-agent/tls/${tlsDomain}.crt" || ! -f "/etc/v2ray-agent/tls/${tlsDomain}.key" ]] || [[ -z $(cat "/etc/v2ray-agent/tls/${tlsDomain}.key") || -z $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]]; then
  1741. tail -n 10 /etc/v2ray-agent/tls/acme.log
  1742. if [[ ${installTLSCount} == "1" ]]; then
  1743. echoContent red " ---> TLS安装失败,请检查acme日志"
  1744. exit 0
  1745. fi
  1746. installTLSCount=1
  1747. echo
  1748. if tail -n 10 /etc/v2ray-agent/tls/acme.log | grep -q "Could not validate email address as valid"; then
  1749. echoContent red " ---> 邮箱无法通过SSL厂商验证,请重新输入"
  1750. echo
  1751. customSSLEmail "validate email"
  1752. installTLS "$1"
  1753. else
  1754. installTLS "$1"
  1755. fi
  1756. fi
  1757. echoContent green " ---> TLS生成成功"
  1758. else
  1759. echoContent yellow " ---> 未安装acme.sh"
  1760. exit 0
  1761. fi
  1762. }
  1763. # 初始化随机字符串
  1764. initRandomPath() {
  1765. local chars="abcdefghijklmnopqrtuxyz"
  1766. local initCustomPath=
  1767. for i in {1..4}; do
  1768. echo "${i}" >/dev/null
  1769. initCustomPath+="${chars:RANDOM%${#chars}:1}"
  1770. done
  1771. customPath=${initCustomPath}
  1772. }
  1773. # 自定义/随机路径
  1774. randomPathFunction() {
  1775. if [[ -n $1 ]]; then
  1776. echoContent skyBlue "\n进度 $1/${totalProgress} : 生成随机路径"
  1777. else
  1778. echoContent skyBlue "生成随机路径"
  1779. fi
  1780. if [[ -n "${currentPath}" && -z "${lastInstallationConfig}" ]]; then
  1781. echo
  1782. read -r -p "读取到上次安装记录,是否使用上次安装时的path路径 ?[y/n]:" historyPathStatus
  1783. echo
  1784. elif [[ -n "${currentPath}" && -n "${lastInstallationConfig}" ]]; then
  1785. historyPathStatus="y"
  1786. fi
  1787. if [[ "${historyPathStatus}" == "y" ]]; then
  1788. customPath=${currentPath}
  1789. echoContent green " ---> 使用成功\n"
  1790. else
  1791. echoContent yellow "请输入自定义路径[例: alone],不需要斜杠,[回车]随机路径"
  1792. read -r -p '路径:' customPath
  1793. if [[ -z "${customPath}" ]]; then
  1794. initRandomPath
  1795. currentPath=${customPath}
  1796. else
  1797. if [[ "${customPath: -2}" == "ws" ]]; then
  1798. echo
  1799. echoContent red " ---> 自定义path结尾不可用ws结尾,否则无法区分分流路径"
  1800. randomPathFunction "$1"
  1801. else
  1802. currentPath=${customPath}
  1803. fi
  1804. fi
  1805. fi
  1806. echoContent yellow "\n path:${currentPath}"
  1807. echoContent skyBlue "\n----------------------------"
  1808. }
  1809. # 随机数
  1810. randomNum() {
  1811. if [[ "${release}" == "alpine" ]]; then
  1812. local ranNum=
  1813. ranNum="$(shuf -i "$1"-"$2" -n 1)"
  1814. echo "${ranNum}"
  1815. else
  1816. echo $((RANDOM % $2 + $1))
  1817. fi
  1818. }
  1819. # Nginx伪装博客
  1820. nginxBlog() {
  1821. if [[ -n "$1" ]]; then
  1822. echoContent skyBlue "\n进度 $1/${totalProgress} : 添加伪装站点"
  1823. else
  1824. echoContent yellow "\n开始添加伪装站点"
  1825. fi
  1826. if [[ -d "${nginxStaticPath}" && -f "${nginxStaticPath}/check" ]]; then
  1827. echo
  1828. if [[ -z "${lastInstallationConfig}" ]]; then
  1829. read -r -p "检测到安装伪装站点,是否需要重新安装[y/n]:" nginxBlogInstallStatus
  1830. else
  1831. nginxBlogInstallStatus="n"
  1832. fi
  1833. if [[ "${nginxBlogInstallStatus}" == "y" ]]; then
  1834. rm -rf "${nginxStaticPath}*"
  1835. # randomNum=$((RANDOM % 6 + 1))
  1836. randomNum=$(randomNum 1 9)
  1837. if [[ "${release}" == "alpine" ]]; then
  1838. wget -q -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip"
  1839. else
  1840. wget -q "${wgetShowProgressStatus}" -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip"
  1841. fi
  1842. unzip -o "${nginxStaticPath}html${randomNum}.zip" -d "${nginxStaticPath}" >/dev/null
  1843. rm -f "${nginxStaticPath}html${randomNum}.zip*"
  1844. echoContent green " ---> 添加伪装站点成功"
  1845. fi
  1846. else
  1847. randomNum=$(randomNum 1 9)
  1848. # randomNum=$((RANDOM % 6 + 1))
  1849. rm -rf "${nginxStaticPath}*"
  1850. if [[ "${release}" == "alpine" ]]; then
  1851. wget -q -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip"
  1852. else
  1853. wget -q "${wgetShowProgressStatus}" -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip"
  1854. fi
  1855. unzip -o "${nginxStaticPath}html${randomNum}.zip" -d "${nginxStaticPath}" >/dev/null
  1856. rm -f "${nginxStaticPath}html${randomNum}.zip*"
  1857. echoContent green " ---> 添加伪装站点成功"
  1858. fi
  1859. }
  1860. # 修改http_port_t端口
  1861. updateSELinuxHTTPPortT() {
  1862. $(find /usr/bin /usr/sbin | grep -w journalctl) -xe >/etc/v2ray-agent/nginx_error.log 2>&1
  1863. if find /usr/bin /usr/sbin | grep -q -w semanage && find /usr/bin /usr/sbin | grep -q -w getenforce && grep -E "31300|31302" </etc/v2ray-agent/nginx_error.log | grep -q "Permission denied"; then
  1864. echoContent red " ---> 检查SELinux端口是否开放"
  1865. if ! $(find /usr/bin /usr/sbin | grep -w semanage) port -l | grep http_port | grep -q 31300; then
  1866. $(find /usr/bin /usr/sbin | grep -w semanage) port -a -t http_port_t -p tcp 31300
  1867. echoContent green " ---> http_port_t 31300 端口开放成功"
  1868. fi
  1869. if ! $(find /usr/bin /usr/sbin | grep -w semanage) port -l | grep http_port | grep -q 31302; then
  1870. $(find /usr/bin /usr/sbin | grep -w semanage) port -a -t http_port_t -p tcp 31302
  1871. echoContent green " ---> http_port_t 31302 端口开放成功"
  1872. fi
  1873. handleNginx start
  1874. else
  1875. exit 0
  1876. fi
  1877. }
  1878. # 操作Nginx
  1879. handleNginx() {
  1880. if ! echo "${selectCustomInstallType}" | grep -qwE ",7,|,8,|,7,8," && [[ -z $(pgrep -f "nginx") ]] && [[ "$1" == "start" ]]; then
  1881. if [[ "${release}" == "alpine" ]]; then
  1882. rc-service nginx start 2>/etc/v2ray-agent/nginx_error.log
  1883. else
  1884. systemctl start nginx 2>/etc/v2ray-agent/nginx_error.log
  1885. fi
  1886. sleep 0.5
  1887. if [[ -z $(pgrep -f "nginx") ]]; then
  1888. echoContent red " ---> Nginx启动失败"
  1889. echoContent red " ---> 请将下方日志反馈给开发者"
  1890. nginx
  1891. if grep -q "journalctl -xe" </etc/v2ray-agent/nginx_error.log; then
  1892. updateSELinuxHTTPPortT
  1893. fi
  1894. else
  1895. echoContent green " ---> Nginx启动成功"
  1896. fi
  1897. elif [[ -n $(pgrep -f "nginx") ]] && [[ "$1" == "stop" ]]; then
  1898. if [[ "${release}" == "alpine" ]]; then
  1899. rc-service nginx stop
  1900. else
  1901. systemctl stop nginx
  1902. fi
  1903. sleep 0.5
  1904. if [[ -z ${btDomain} && -n $(pgrep -f "nginx") ]]; then
  1905. pgrep -f "nginx" | xargs kill -9
  1906. fi
  1907. echoContent green " ---> Nginx关闭成功"
  1908. fi
  1909. }
  1910. # 定时任务更新tls证书
  1911. installCronTLS() {
  1912. if [[ -z "${btDomain}" ]]; then
  1913. echoContent skyBlue "\n进度 $1/${totalProgress} : 添加定时维护证书"
  1914. crontab -l >/etc/v2ray-agent/backup_crontab.cron
  1915. local historyCrontab
  1916. historyCrontab=$(sed '/v2ray-agent/d;/acme.sh/d' /etc/v2ray-agent/backup_crontab.cron)
  1917. echo "${historyCrontab}" >/etc/v2ray-agent/backup_crontab.cron
  1918. echo "30 1 * * * /bin/bash /etc/v2ray-agent/install.sh RenewTLS >> /etc/v2ray-agent/crontab_tls.log 2>&1" >>/etc/v2ray-agent/backup_crontab.cron
  1919. crontab /etc/v2ray-agent/backup_crontab.cron
  1920. echoContent green "\n ---> 添加定时维护证书成功"
  1921. fi
  1922. }
  1923. # 定时任务更新geo文件
  1924. installCronUpdateGeo() {
  1925. if [[ "${coreInstallType}" == "1" ]]; then
  1926. if crontab -l | grep -q "UpdateGeo"; then
  1927. echoContent red "\n ---> 已添加自动更新定时任务,请不要重复添加"
  1928. exit 0
  1929. fi
  1930. echoContent skyBlue "\n进度 1/1 : 添加定时更新geo文件"
  1931. crontab -l >/etc/v2ray-agent/backup_crontab.cron
  1932. echo "35 1 * * * /bin/bash /etc/v2ray-agent/install.sh UpdateGeo >> /etc/v2ray-agent/crontab_tls.log 2>&1" >>/etc/v2ray-agent/backup_crontab.cron
  1933. crontab /etc/v2ray-agent/backup_crontab.cron
  1934. echoContent green "\n ---> 添加定时更新geo文件成功"
  1935. fi
  1936. }
  1937. # 更新证书
  1938. renewalTLS() {
  1939. if [[ -n $1 ]]; then
  1940. echoContent skyBlue "\n进度 $1/1 : 更新证书"
  1941. fi
  1942. readAcmeTLS
  1943. local domain=${currentHost}
  1944. if [[ -z "${currentHost}" && -n "${tlsDomain}" ]]; then
  1945. domain=${tlsDomain}
  1946. fi
  1947. if [[ -f "/etc/v2ray-agent/tls/ssl_type" ]]; then
  1948. if grep -q "buypass" <"/etc/v2ray-agent/tls/ssl_type"; then
  1949. sslRenewalDays=180
  1950. fi
  1951. fi
  1952. if [[ -d "$HOME/.acme.sh/${domain}_ecc" && -f "$HOME/.acme.sh/${domain}_ecc/${domain}.key" && -f "$HOME/.acme.sh/${domain}_ecc/${domain}.cer" ]] || [[ "${installedDNSAPIStatus}" == "true" ]]; then
  1953. modifyTime=
  1954. if [[ "${installedDNSAPIStatus}" == "true" ]]; then
  1955. modifyTime=$(stat --format=%z "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc/*.${dnsTLSDomain}.cer")
  1956. else
  1957. modifyTime=$(stat --format=%z "$HOME/.acme.sh/${domain}_ecc/${domain}.cer")
  1958. fi
  1959. modifyTime=$(date +%s -d "${modifyTime}")
  1960. currentTime=$(date +%s)
  1961. ((stampDiff = currentTime - modifyTime))
  1962. ((days = stampDiff / 86400))
  1963. ((remainingDays = sslRenewalDays - days))
  1964. tlsStatus=${remainingDays}
  1965. if [[ ${remainingDays} -le 0 ]]; then
  1966. tlsStatus="已过期"
  1967. fi
  1968. echoContent skyBlue " ---> 证书检查日期:$(date "+%F %H:%M:%S")"
  1969. echoContent skyBlue " ---> 证书生成日期:$(date -d @"${modifyTime}" +"%F %H:%M:%S")"
  1970. echoContent skyBlue " ---> 证书生成天数:${days}"
  1971. echoContent skyBlue " ---> 证书剩余天数:"${tlsStatus}
  1972. echoContent skyBlue " ---> 证书过期前最后一天自动更新,如更新失败请手动更新"
  1973. if [[ ${remainingDays} -le 1 ]]; then
  1974. echoContent yellow " ---> 重新生成证书"
  1975. handleNginx stop
  1976. if [[ "${coreInstallType}" == "1" ]]; then
  1977. handleXray stop
  1978. elif [[ "${coreInstallType}" == "2" ]]; then
  1979. handleV2Ray stop
  1980. fi
  1981. sudo "$HOME/.acme.sh/acme.sh" --cron --home "$HOME/.acme.sh"
  1982. sudo "$HOME/.acme.sh/acme.sh" --installcert -d "${domain}" --fullchainpath /etc/v2ray-agent/tls/"${domain}.crt" --keypath /etc/v2ray-agent/tls/"${domain}.key" --ecc
  1983. reloadCore
  1984. handleNginx start
  1985. else
  1986. echoContent green " ---> 证书有效"
  1987. fi
  1988. elif [[ -f "/etc/v2ray-agent/tls/${tlsDomain}.crt" && -f "/etc/v2ray-agent/tls/${tlsDomain}.key" && -n $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]]; then
  1989. echoContent yellow " ---> 检测到使用自定义证书,无法执行renew操作。"
  1990. else
  1991. echoContent red " ---> 未安装"
  1992. fi
  1993. }
  1994. # 安装 sing-box
  1995. installSingBox() {
  1996. readInstallType
  1997. echoContent skyBlue "\n进度 $1/${totalProgress} : 安装sing-box"
  1998. if [[ ! -f "/etc/v2ray-agent/sing-box/sing-box" ]]; then
  1999. version=$(curl -s "https://api.github.com/repos/SagerNet/sing-box/releases?per_page=20" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1)
  2000. echoContent green " ---> sing-box版本:${version}"
  2001. if [[ "${release}" == "alpine" ]]; then
  2002. wget -c -q -P /etc/v2ray-agent/sing-box/ "https://github.com/SagerNet/sing-box/releases/download/${version}/sing-box-${version/v/}${singBoxCoreCPUVendor}.tar.gz"
  2003. else
  2004. wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/sing-box/ "https://github.com/SagerNet/sing-box/releases/download/${version}/sing-box-${version/v/}${singBoxCoreCPUVendor}.tar.gz"
  2005. fi
  2006. if [[ ! -f "/etc/v2ray-agent/sing-box/sing-box-${version/v/}${singBoxCoreCPUVendor}.tar.gz" ]]; then
  2007. read -r -p "核心下载失败,请重新尝试安装,是否重新尝试?[y/n]" downloadStatus
  2008. if [[ "${downloadStatus}" == "y" ]]; then
  2009. installSingBox "$1"
  2010. fi
  2011. else
  2012. tar zxvf "/etc/v2ray-agent/sing-box/sing-box-${version/v/}${singBoxCoreCPUVendor}.tar.gz" -C "/etc/v2ray-agent/sing-box/" >/dev/null 2>&1
  2013. mv "/etc/v2ray-agent/sing-box/sing-box-${version/v/}${singBoxCoreCPUVendor}/sing-box" /etc/v2ray-agent/sing-box/sing-box
  2014. rm -rf /etc/v2ray-agent/sing-box/sing-box-*
  2015. chmod 655 /etc/v2ray-agent/sing-box/sing-box
  2016. fi
  2017. else
  2018. echoContent green " ---> sing-box版本:v$(/etc/v2ray-agent/sing-box/sing-box version | grep "sing-box version" | awk '{print $3}')"
  2019. if [[ -z "${lastInstallationConfig}" ]]; then
  2020. read -r -p "是否更新、升级?[y/n]:" reInstallSingBoxStatus
  2021. if [[ "${reInstallSingBoxStatus}" == "y" ]]; then
  2022. rm -f /etc/v2ray-agent/sing-box/sing-box
  2023. installSingBox "$1"
  2024. fi
  2025. fi
  2026. fi
  2027. }
  2028. # 检查wget showProgress
  2029. checkWgetShowProgress() {
  2030. if [[ "${release}" != "alpine" ]]; then
  2031. if find /usr/bin /usr/sbin | grep -q "/wget" && wget --help | grep -q show-progress; then
  2032. wgetShowProgressStatus="--show-progress"
  2033. fi
  2034. fi
  2035. }
  2036. # 安装xray
  2037. installXray() {
  2038. readInstallType
  2039. local prereleaseStatus=false
  2040. if [[ "$2" == "true" ]]; then
  2041. prereleaseStatus=true
  2042. fi
  2043. echoContent skyBlue "\n进度 $1/${totalProgress} : 安装Xray"
  2044. if [[ ! -f "/etc/v2ray-agent/xray/xray" ]]; then
  2045. version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=5" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1)
  2046. echoContent green " ---> Xray-core版本:${version}"
  2047. if [[ "${release}" == "alpine" ]]; then
  2048. wget -c -q -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip"
  2049. else
  2050. wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip"
  2051. fi
  2052. if [[ ! -f "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" ]]; then
  2053. read -r -p "核心下载失败,请重新尝试安装,是否重新尝试?[y/n]" downloadStatus
  2054. if [[ "${downloadStatus}" == "y" ]]; then
  2055. installXray "$1"
  2056. fi
  2057. else
  2058. unzip -o "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" -d /etc/v2ray-agent/xray >/dev/null
  2059. rm -rf "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip"
  2060. version=$(curl -s https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases?per_page=1 | jq -r '.[]|.tag_name')
  2061. echoContent skyBlue "------------------------Version-------------------------------"
  2062. echo "version:${version}"
  2063. rm /etc/v2ray-agent/xray/geo* >/dev/null 2>&1
  2064. if [[ "${release}" == "alpine" ]]; then
  2065. wget -c -q -P /etc/v2ray-agent/xray/ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geosite.dat"
  2066. wget -c -q -P /etc/v2ray-agent/xray/ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geoip.dat"
  2067. else
  2068. wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geosite.dat"
  2069. wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geoip.dat"
  2070. fi
  2071. chmod 655 /etc/v2ray-agent/xray/xray
  2072. fi
  2073. else
  2074. if [[ -z "${lastInstallationConfig}" ]]; then
  2075. echoContent green " ---> Xray-core版本:$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)"
  2076. read -r -p "是否更新、升级?[y/n]:" reInstallXrayStatus
  2077. if [[ "${reInstallXrayStatus}" == "y" ]]; then
  2078. rm -f /etc/v2ray-agent/xray/xray
  2079. installXray "$1" "$2"
  2080. fi
  2081. fi
  2082. fi
  2083. }
  2084. # xray版本管理
  2085. xrayVersionManageMenu() {
  2086. echoContent skyBlue "\n进度 $1/${totalProgress} : Xray版本管理"
  2087. if [[ "${coreInstallType}" != "1" ]]; then
  2088. echoContent red " ---> 没有检测到安装目录,请执行脚本安装内容"
  2089. exit 0
  2090. fi
  2091. echoContent red "\n=============================================================="
  2092. echoContent yellow "1.升级Xray-core"
  2093. echoContent yellow "2.升级Xray-core 预览版"
  2094. echoContent yellow "3.回退Xray-core"
  2095. echoContent yellow "4.关闭Xray-core"
  2096. echoContent yellow "5.打开Xray-core"
  2097. echoContent yellow "6.重启Xray-core"
  2098. echoContent yellow "7.更新geosite、geoip"
  2099. echoContent yellow "8.设置自动更新geo文件[每天凌晨更新]"
  2100. echoContent yellow "9.查看日志"
  2101. echoContent red "=============================================================="
  2102. read -r -p "请选择:" selectXrayType
  2103. if [[ "${selectXrayType}" == "1" ]]; then
  2104. prereleaseStatus=false
  2105. updateXray
  2106. elif [[ "${selectXrayType}" == "2" ]]; then
  2107. prereleaseStatus=true
  2108. updateXray
  2109. elif [[ "${selectXrayType}" == "3" ]]; then
  2110. echoContent yellow "\n1.只可以回退最近的五个版本"
  2111. echoContent yellow "2.不保证回退后一定可以正常使用"
  2112. echoContent yellow "3.如果回退的版本不支持当前的config,则会无法连接,谨慎操作"
  2113. echoContent skyBlue "------------------------Version-------------------------------"
  2114. curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=5" | jq -r ".[]|select (.prerelease==false)|.tag_name" | awk '{print ""NR""":"$0}'
  2115. echoContent skyBlue "--------------------------------------------------------------"
  2116. read -r -p "请输入要回退的版本:" selectXrayVersionType
  2117. version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=5" | jq -r ".[]|select (.prerelease==false)|.tag_name" | awk '{print ""NR""":"$0}' | grep "${selectXrayVersionType}:" | awk -F "[:]" '{print $2}')
  2118. if [[ -n "${version}" ]]; then
  2119. updateXray "${version}"
  2120. else
  2121. echoContent red "\n ---> 输入有误,请重新输入"
  2122. xrayVersionManageMenu 1
  2123. fi
  2124. elif [[ "${selectXrayType}" == "4" ]]; then
  2125. handleXray stop
  2126. elif [[ "${selectXrayType}" == "5" ]]; then
  2127. handleXray start
  2128. elif [[ "${selectXrayType}" == "6" ]]; then
  2129. reloadCore
  2130. elif [[ "${selectXrayType}" == "7" ]]; then
  2131. updateGeoSite
  2132. elif [[ "${selectXrayType}" == "8" ]]; then
  2133. installCronUpdateGeo
  2134. elif [[ "${selectXrayType}" == "9" ]]; then
  2135. checkLog 1
  2136. fi
  2137. }
  2138. # 更新 geosite
  2139. updateGeoSite() {
  2140. echoContent yellow "\n来源 https://github.com/Loyalsoldier/v2ray-rules-dat"
  2141. version=$(curl -s https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases?per_page=1 | jq -r '.[]|.tag_name')
  2142. echoContent skyBlue "------------------------Version-------------------------------"
  2143. echo "version:${version}"
  2144. rm ${configPath}../geo* >/dev/null
  2145. if [[ "${release}" == "alpine" ]]; then
  2146. wget -c -q -P ${configPath}../ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geosite.dat"
  2147. wget -c -q -P ${configPath}../ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geoip.dat"
  2148. else
  2149. wget -c -q "${wgetShowProgressStatus}" -P ${configPath}../ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geosite.dat"
  2150. wget -c -q "${wgetShowProgressStatus}" -P ${configPath}../ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geoip.dat"
  2151. fi
  2152. reloadCore
  2153. echoContent green " ---> 更新完毕"
  2154. }
  2155. # 更新Xray
  2156. updateXray() {
  2157. readInstallType
  2158. if [[ -z "${coreInstallType}" || "${coreInstallType}" != "1" ]]; then
  2159. if [[ -n "$1" ]]; then
  2160. version=$1
  2161. else
  2162. version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=5" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1)
  2163. fi
  2164. echoContent green " ---> Xray-core版本:${version}"
  2165. if [[ "${release}" == "alpine" ]]; then
  2166. wget -c -q -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip"
  2167. else
  2168. wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip"
  2169. fi
  2170. unzip -o "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" -d /etc/v2ray-agent/xray >/dev/null
  2171. rm -rf "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip"
  2172. chmod 655 /etc/v2ray-agent/xray/xray
  2173. handleXray stop
  2174. handleXray start
  2175. else
  2176. echoContent green " ---> 当前Xray-core版本:$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)"
  2177. if [[ -n "$1" ]]; then
  2178. version=$1
  2179. else
  2180. version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=10" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1)
  2181. fi
  2182. if [[ -n "$1" ]]; then
  2183. read -r -p "回退版本为${version},是否继续?[y/n]:" rollbackXrayStatus
  2184. if [[ "${rollbackXrayStatus}" == "y" ]]; then
  2185. echoContent green " ---> 当前Xray-core版本:$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)"
  2186. handleXray stop
  2187. rm -f /etc/v2ray-agent/xray/xray
  2188. updateXray "${version}"
  2189. else
  2190. echoContent green " ---> 放弃回退版本"
  2191. fi
  2192. elif [[ "${version}" == "v$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" ]]; then
  2193. read -r -p "当前版本与最新版相同,是否重新安装?[y/n]:" reInstallXrayStatus
  2194. if [[ "${reInstallXrayStatus}" == "y" ]]; then
  2195. handleXray stop
  2196. rm -f /etc/v2ray-agent/xray/xray
  2197. updateXray
  2198. else
  2199. echoContent green " ---> 放弃重新安装"
  2200. fi
  2201. else
  2202. read -r -p "最新版本为:${version},是否更新?[y/n]:" installXrayStatus
  2203. if [[ "${installXrayStatus}" == "y" ]]; then
  2204. rm /etc/v2ray-agent/xray/xray
  2205. updateXray
  2206. else
  2207. echoContent green " ---> 放弃更新"
  2208. fi
  2209. fi
  2210. fi
  2211. }
  2212. # 验证整个服务是否可用
  2213. checkGFWStatue() {
  2214. readInstallType
  2215. echoContent skyBlue "\n进度 $1/${totalProgress} : 验证服务启动状态"
  2216. if [[ "${coreInstallType}" == "1" ]] && [[ -n $(pgrep -f "xray/xray") ]]; then
  2217. echoContent green " ---> 服务启动成功"
  2218. elif [[ "${coreInstallType}" == "2" ]] && [[ -n $(pgrep -f "sing-box/sing-box") ]]; then
  2219. echoContent green " ---> 服务启动成功"
  2220. else
  2221. echoContent red " ---> 服务启动失败,请检查终端是否有日志打印"
  2222. exit 0
  2223. fi
  2224. }
  2225. # 安装alpine开机启动
  2226. installAlpineStartup() {
  2227. local serviceName=$1
  2228. if [[ "${serviceName}" == "sing-box" ]]; then
  2229. cat <<EOF >"/etc/init.d/${serviceName}"
  2230. #!/sbin/openrc-run
  2231. description="sing-box service"
  2232. command="/etc/v2ray-agent/sing-box/sing-box"
  2233. command_args="run -c /etc/v2ray-agent/sing-box/conf/config.json"
  2234. command_background=true
  2235. pidfile="/var/run/sing-box.pid"
  2236. EOF
  2237. elif [[ "${serviceName}" == "xray" ]]; then
  2238. cat <<EOF >"/etc/init.d/${serviceName}"
  2239. #!/sbin/openrc-run
  2240. description="xray service"
  2241. command="/etc/v2ray-agent/xray/xray"
  2242. command_args="run -confdir /etc/v2ray-agent/xray/conf"
  2243. command_background=true
  2244. pidfile="/var/run/xray.pid"
  2245. EOF
  2246. fi
  2247. chmod +x "/etc/init.d/${serviceName}"
  2248. }
  2249. # sing-box开机自启
  2250. installSingBoxService() {
  2251. echoContent skyBlue "\n进度 $1/${totalProgress} : 配置sing-box开机自启"
  2252. execStart='/etc/v2ray-agent/sing-box/sing-box run -c /etc/v2ray-agent/sing-box/conf/config.json'
  2253. if [[ -n $(find /bin /usr/bin -name "systemctl") && "${release}" != "alpine" ]]; then
  2254. rm -rf /etc/systemd/system/sing-box.service
  2255. touch /etc/systemd/system/sing-box.service
  2256. cat <<EOF >/etc/systemd/system/sing-box.service
  2257. [Unit]
  2258. Description=Sing-Box Service
  2259. Documentation=https://sing-box.sagernet.org
  2260. After=network.target nss-lookup.target
  2261. [Service]
  2262. User=root
  2263. WorkingDirectory=/root
  2264. CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
  2265. AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH
  2266. ExecStart=${execStart}
  2267. ExecReload=/bin/kill -HUP $MAINPID
  2268. Restart=on-failure
  2269. RestartSec=10
  2270. LimitNPROC=infinity
  2271. LimitNOFILE=infinity
  2272. [Install]
  2273. WantedBy=multi-user.target
  2274. EOF
  2275. bootStartup "sing-box.service"
  2276. elif [[ "${release}" == "alpine" ]]; then
  2277. installAlpineStartup "sing-box"
  2278. bootStartup "sing-box"
  2279. fi
  2280. echoContent green " ---> 配置sing-box开机启动完毕"
  2281. }
  2282. # Xray开机自启
  2283. installXrayService() {
  2284. echoContent skyBlue "\n进度 $1/${totalProgress} : 配置Xray开机自启"
  2285. execStart='/etc/v2ray-agent/xray/xray run -confdir /etc/v2ray-agent/xray/conf'
  2286. if [[ -n $(find /bin /usr/bin -name "systemctl") ]]; then
  2287. rm -rf /etc/systemd/system/xray.service
  2288. touch /etc/systemd/system/xray.service
  2289. cat <<EOF >/etc/systemd/system/xray.service
  2290. [Unit]
  2291. Description=Xray Service
  2292. Documentation=https://github.com/xtls
  2293. After=network.target nss-lookup.target
  2294. [Service]
  2295. User=root
  2296. ExecStart=${execStart}
  2297. Restart=on-failure
  2298. RestartPreventExitStatus=23
  2299. LimitNPROC=infinity
  2300. LimitNOFILE=infinity
  2301. [Install]
  2302. WantedBy=multi-user.target
  2303. EOF
  2304. bootStartup "xray.service"
  2305. echoContent green " ---> 配置Xray开机自启成功"
  2306. elif [[ "${release}" == "alpine" ]]; then
  2307. installAlpineStartup "xray"
  2308. bootStartup "xray"
  2309. fi
  2310. }
  2311. # 操作Hysteria
  2312. handleHysteria() {
  2313. # shellcheck disable=SC2010
  2314. if find /bin /usr/bin | grep -q systemctl && ls /etc/systemd/system/ | grep -q hysteria.service; then
  2315. if [[ -z $(pgrep -f "hysteria/hysteria") ]] && [[ "$1" == "start" ]]; then
  2316. systemctl start hysteria.service
  2317. elif [[ -n $(pgrep -f "hysteria/hysteria") ]] && [[ "$1" == "stop" ]]; then
  2318. systemctl stop hysteria.service
  2319. fi
  2320. fi
  2321. sleep 0.8
  2322. if [[ "$1" == "start" ]]; then
  2323. if [[ -n $(pgrep -f "hysteria/hysteria") ]]; then
  2324. echoContent green " ---> Hysteria启动成功"
  2325. else
  2326. echoContent red "Hysteria启动失败"
  2327. echoContent red "请手动执行【/etc/v2ray-agent/hysteria/hysteria --log-level debug -c /etc/v2ray-agent/hysteria/conf/config.json server】,查看错误日志"
  2328. exit 0
  2329. fi
  2330. elif [[ "$1" == "stop" ]]; then
  2331. if [[ -z $(pgrep -f "hysteria/hysteria") ]]; then
  2332. echoContent green " ---> Hysteria关闭成功"
  2333. else
  2334. echoContent red "Hysteria关闭失败"
  2335. echoContent red "请手动执行【ps -ef|grep -v grep|grep hysteria|awk '{print \$2}'|xargs kill -9】"
  2336. exit 0
  2337. fi
  2338. fi
  2339. }
  2340. # 操作sing-box
  2341. handleSingBox() {
  2342. if [[ -f "/etc/systemd/system/sing-box.service" ]]; then
  2343. if [[ -z $(pgrep -f "sing-box") ]] && [[ "$1" == "start" ]]; then
  2344. singBoxMergeConfig
  2345. systemctl start sing-box.service
  2346. elif [[ -n $(pgrep -f "sing-box") ]] && [[ "$1" == "stop" ]]; then
  2347. systemctl stop sing-box.service
  2348. fi
  2349. elif [[ -f "/etc/init.d/sing-box" ]]; then
  2350. if [[ -z $(pgrep -f "sing-box") ]] && [[ "$1" == "start" ]]; then
  2351. singBoxMergeConfig
  2352. rc-service sing-box start
  2353. elif [[ -n $(pgrep -f "sing-box") ]] && [[ "$1" == "stop" ]]; then
  2354. rc-service sing-box stop
  2355. fi
  2356. fi
  2357. sleep 1
  2358. if [[ "$1" == "start" ]]; then
  2359. if [[ -n $(pgrep -f "sing-box") ]]; then
  2360. echoContent green " ---> sing-box启动成功"
  2361. else
  2362. echoContent red "sing-box启动失败"
  2363. echoContent yellow "请手动执行【 /etc/v2ray-agent/sing-box/sing-box merge config.json -C /etc/v2ray-agent/sing-box/conf/config/ -D /etc/v2ray-agent/sing-box/conf/ 】,查看错误日志"
  2364. echo
  2365. echoContent yellow "如上面命令没有错误,请手动执行【 /etc/v2ray-agent/sing-box/sing-box run -c /etc/v2ray-agent/sing-box/conf/config.json 】,查看错误日志"
  2366. exit 0
  2367. fi
  2368. elif [[ "$1" == "stop" ]]; then
  2369. if [[ -z $(pgrep -f "sing-box") ]]; then
  2370. echoContent green " ---> sing-box关闭成功"
  2371. else
  2372. echoContent red " ---> sing-box关闭失败"
  2373. echoContent red "请手动执行【ps -ef|grep -v grep|grep sing-box|awk '{print \$2}'|xargs kill -9】"
  2374. exit 0
  2375. fi
  2376. fi
  2377. }
  2378. # 操作xray
  2379. handleXray() {
  2380. if [[ -n $(find /bin /usr/bin -name "systemctl") ]] && [[ -n $(find /etc/systemd/system/ -name "xray.service") ]]; then
  2381. if [[ -z $(pgrep -f "xray/xray") ]] && [[ "$1" == "start" ]]; then
  2382. systemctl start xray.service
  2383. elif [[ -n $(pgrep -f "xray/xray") ]] && [[ "$1" == "stop" ]]; then
  2384. systemctl stop xray.service
  2385. fi
  2386. elif [[ -f "/etc/init.d/xray" ]]; then
  2387. if [[ -z $(pgrep -f "xray/xray") ]] && [[ "$1" == "start" ]]; then
  2388. rc-service xray start
  2389. elif [[ -n $(pgrep -f "xray/xray") ]] && [[ "$1" == "stop" ]]; then
  2390. rc-service xray stop
  2391. fi
  2392. fi
  2393. sleep 0.8
  2394. if [[ "$1" == "start" ]]; then
  2395. if [[ -n $(pgrep -f "xray/xray") ]]; then
  2396. echoContent green " ---> Xray启动成功"
  2397. else
  2398. echoContent red "Xray启动失败"
  2399. echoContent red "请手动执行以下的命令后【/etc/v2ray-agent/xray/xray -confdir /etc/v2ray-agent/xray/conf】将错误日志进行反馈"
  2400. exit 0
  2401. fi
  2402. elif [[ "$1" == "stop" ]]; then
  2403. if [[ -z $(pgrep -f "xray/xray") ]]; then
  2404. echoContent green " ---> Xray关闭成功"
  2405. else
  2406. echoContent red "xray关闭失败"
  2407. echoContent red "请手动执行【ps -ef|grep -v grep|grep xray|awk '{print \$2}'|xargs kill -9】"
  2408. exit 0
  2409. fi
  2410. fi
  2411. }
  2412. # 读取Xray用户数据并初始化
  2413. initXrayClients() {
  2414. local type=",$1,"
  2415. local newUUID=$2
  2416. local newEmail=$3
  2417. if [[ -n "${newUUID}" ]]; then
  2418. local newUser=
  2419. newUser="{\"id\":\"${uuid}\",\"flow\":\"xtls-rprx-vision\",\"email\":\"${newEmail}-VLESS_TCP/TLS_Vision\"}"
  2420. currentClients=$(echo "${currentClients}" | jq -r ". +=[${newUser}]")
  2421. fi
  2422. local users=
  2423. users=[]
  2424. while read -r user; do
  2425. uuid=$(echo "${user}" | jq -r .id//.uuid)
  2426. email=$(echo "${user}" | jq -r .email//.name | awk -F "[-]" '{print $1}')
  2427. currentUser=
  2428. if echo "${type}" | grep -q "0"; then
  2429. currentUser="{\"id\":\"${uuid}\",\"flow\":\"xtls-rprx-vision\",\"email\":\"${email}-VLESS_TCP/TLS_Vision\"}"
  2430. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2431. fi
  2432. # VLESS WS
  2433. if echo "${type}" | grep -q ",1,"; then
  2434. currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-VLESS_WS\"}"
  2435. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2436. fi
  2437. # VLESS XHTTP
  2438. if echo "${type}" | grep -q ",12,"; then
  2439. currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-VLESS_XHTTP\"}"
  2440. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2441. fi
  2442. # trojan grpc
  2443. if echo "${type}" | grep -q ",2,"; then
  2444. currentUser="{\"password\":\"${uuid}\",\"email\":\"${email}-Trojan_gRPC\"}"
  2445. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2446. fi
  2447. # VMess WS
  2448. if echo "${type}" | grep -q ",3,"; then
  2449. currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-VMess_WS\",\"alterId\": 0}"
  2450. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2451. fi
  2452. # trojan tcp
  2453. if echo "${type}" | grep -q ",4,"; then
  2454. currentUser="{\"password\":\"${uuid}\",\"email\":\"${email}-trojan_tcp\"}"
  2455. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2456. fi
  2457. # vless grpc
  2458. if echo "${type}" | grep -q ",5,"; then
  2459. currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-vless_grpc\"}"
  2460. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2461. fi
  2462. # hysteria
  2463. if echo "${type}" | grep -q ",6,"; then
  2464. currentUser="{\"password\":\"${uuid}\",\"name\":\"${email}-singbox_hysteria2\"}"
  2465. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2466. fi
  2467. # vless reality vision
  2468. if echo "${type}" | grep -q ",7,"; then
  2469. currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-vless_reality_vision\",\"flow\":\"xtls-rprx-vision\"}"
  2470. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2471. fi
  2472. # vless reality grpc
  2473. if echo "${type}" | grep -q ",8,"; then
  2474. currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-vless_reality_grpc\",\"flow\":\"\"}"
  2475. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2476. fi
  2477. # tuic
  2478. if echo "${type}" | grep -q ",9,"; then
  2479. currentUser="{\"uuid\":\"${uuid}\",\"password\":\"${uuid}\",\"name\":\"${email}-singbox_tuic\"}"
  2480. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2481. fi
  2482. done < <(echo "${currentClients}" | jq -c '.[]')
  2483. echo "${users}"
  2484. }
  2485. # 读取singbox用户数据并初始化
  2486. initSingBoxClients() {
  2487. local type=",$1,"
  2488. local newUUID=$2
  2489. local newName=$3
  2490. if [[ -n "${newUUID}" ]]; then
  2491. local newUser=
  2492. newUser="{\"uuid\":\"${newUUID}\",\"flow\":\"xtls-rprx-vision\",\"name\":\"${newName}-VLESS_TCP/TLS_Vision\"}"
  2493. currentClients=$(echo "${currentClients}" | jq -r ". +=[${newUser}]")
  2494. fi
  2495. local users=
  2496. users=[]
  2497. while read -r user; do
  2498. uuid=$(echo "${user}" | jq -r .uuid//.id//.password)
  2499. name=$(echo "${user}" | jq -r .name//.email//.username | awk -F "[-]" '{print $1}')
  2500. currentUser=
  2501. # VLESS Vision
  2502. if echo "${type}" | grep -q ",0,"; then
  2503. currentUser="{\"uuid\":\"${uuid}\",\"flow\":\"xtls-rprx-vision\",\"name\":\"${name}-VLESS_TCP/TLS_Vision\"}"
  2504. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2505. fi
  2506. # VLESS WS
  2507. if echo "${type}" | grep -q ",1,"; then
  2508. currentUser="{\"uuid\":\"${uuid}\",\"name\":\"${name}-VLESS_WS\"}"
  2509. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2510. fi
  2511. # VMess ws
  2512. if echo "${type}" | grep -q ",3,"; then
  2513. currentUser="{\"uuid\":\"${uuid}\",\"name\":\"${name}-VMess_WS\",\"alterId\": 0}"
  2514. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2515. fi
  2516. # trojan
  2517. if echo "${type}" | grep -q ",4,"; then
  2518. currentUser="{\"password\":\"${uuid}\",\"name\":\"${name}-Trojan_TCP\"}"
  2519. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2520. fi
  2521. # VLESS Reality Vision
  2522. if echo "${type}" | grep -q ",7,"; then
  2523. currentUser="{\"uuid\":\"${uuid}\",\"flow\":\"xtls-rprx-vision\",\"name\":\"${name}-VLESS_Reality_Vision\"}"
  2524. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2525. fi
  2526. # VLESS Reality gRPC
  2527. if echo "${type}" | grep -q ",8,"; then
  2528. currentUser="{\"uuid\":\"${uuid}\",\"name\":\"${name}-VLESS_Reality_gPRC\"}"
  2529. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2530. fi
  2531. # hysteria2
  2532. if echo "${type}" | grep -q ",6,"; then
  2533. currentUser="{\"password\":\"${uuid}\",\"name\":\"${name}-singbox_hysteria2\"}"
  2534. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2535. fi
  2536. # tuic
  2537. if echo "${type}" | grep -q ",9,"; then
  2538. currentUser="{\"uuid\":\"${uuid}\",\"password\":\"${uuid}\",\"name\":\"${name}-singbox_tuic\"}"
  2539. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2540. fi
  2541. # naive
  2542. if echo "${type}" | grep -q ",10,"; then
  2543. currentUser="{\"password\":\"${uuid}\",\"username\":\"${name}-singbox_naive\"}"
  2544. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2545. fi
  2546. # VMess HTTPUpgrade
  2547. if echo "${type}" | grep -q ",11,"; then
  2548. currentUser="{\"uuid\":\"${uuid}\",\"name\":\"${name}-VMess_HTTPUpgrade\",\"alterId\": 0}"
  2549. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2550. fi
  2551. # anytls
  2552. if echo "${type}" | grep -q ",13,"; then
  2553. currentUser="{\"password\":\"${uuid}\",\"name\":\"${name}-anytls\"}"
  2554. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2555. fi
  2556. if echo "${type}" | grep -q ",20,"; then
  2557. currentUser="{\"username\":\"${uuid}\",\"password\":\"${uuid}\"}"
  2558. users=$(echo "${users}" | jq -r ". +=[${currentUser}]")
  2559. fi
  2560. done < <(echo "${currentClients}" | jq -c '.[]')
  2561. echo "${users}"
  2562. }
  2563. # 初始化hysteria端口
  2564. initHysteriaPort() {
  2565. readSingBoxConfig
  2566. if [[ -n "${hysteriaPort}" ]]; then
  2567. read -r -p "读取到上次安装时的端口,是否使用上次安装时的端口?[y/n]:" historyHysteriaPortStatus
  2568. if [[ "${historyHysteriaPortStatus}" == "y" ]]; then
  2569. echoContent yellow "\n ---> 端口: ${hysteriaPort}"
  2570. else
  2571. hysteriaPort=
  2572. fi
  2573. fi
  2574. if [[ -z "${hysteriaPort}" ]]; then
  2575. echoContent yellow "请输入Hysteria端口[回车随机10000-30000],不可与其他服务重复"
  2576. read -r -p "端口:" hysteriaPort
  2577. if [[ -z "${hysteriaPort}" ]]; then
  2578. hysteriaPort=$((RANDOM % 20001 + 10000))
  2579. fi
  2580. fi
  2581. if [[ -z ${hysteriaPort} ]]; then
  2582. echoContent red " ---> 端口不可为空"
  2583. initHysteriaPort "$2"
  2584. elif ((hysteriaPort < 1 || hysteriaPort > 65535)); then
  2585. echoContent red " ---> 端口不合法"
  2586. initHysteriaPort "$2"
  2587. fi
  2588. allowPort "${hysteriaPort}"
  2589. allowPort "${hysteriaPort}" "udp"
  2590. }
  2591. # 初始化hysteria网络信息
  2592. initHysteria2Network() {
  2593. echoContent yellow "请输入本地带宽峰值的下行速度(默认:100,单位:Mbps)"
  2594. read -r -p "下行速度:" hysteria2ClientDownloadSpeed
  2595. if [[ -z "${hysteria2ClientDownloadSpeed}" ]]; then
  2596. hysteria2ClientDownloadSpeed=100
  2597. echoContent yellow "\n ---> 下行速度: ${hysteria2ClientDownloadSpeed}\n"
  2598. fi
  2599. echoContent yellow "请输入本地带宽峰值的上行速度(默认:50,单位:Mbps)"
  2600. read -r -p "上行速度:" hysteria2ClientUploadSpeed
  2601. if [[ -z "${hysteria2ClientUploadSpeed}" ]]; then
  2602. hysteria2ClientUploadSpeed=50
  2603. echoContent yellow "\n ---> 上行速度: ${hysteria2ClientUploadSpeed}\n"
  2604. fi
  2605. }
  2606. # firewalld设置端口跳跃
  2607. addFirewalldPortHopping() {
  2608. local start=$1
  2609. local end=$2
  2610. local targetPort=$3
  2611. for port in $(seq "$start" "$end"); do
  2612. sudo firewall-cmd --permanent --add-forward-port=port="${port}":proto=udp:toport="${targetPort}"
  2613. done
  2614. sudo firewall-cmd --reload
  2615. }
  2616. # 端口跳跃
  2617. addPortHopping() {
  2618. local type=$1
  2619. local targetPort=$2
  2620. if [[ -n "${portHoppingStart}" || -n "${portHoppingEnd}" ]]; then
  2621. echoContent red " ---> 已添加不可重复添加,可删除后重新添加"
  2622. exit 0
  2623. fi
  2624. if [[ "${release}" == "centos" ]]; then
  2625. if ! systemctl status firewalld 2>/dev/null | grep -q "active (running)"; then
  2626. echoContent red " ---> 未启动firewalld防火墙,无法设置端口跳跃。"
  2627. exit 0
  2628. fi
  2629. fi
  2630. echoContent skyBlue "\n进度 1/1 : 端口跳跃"
  2631. echoContent red "\n=============================================================="
  2632. echoContent yellow "# 注意事项\n"
  2633. echoContent yellow "仅支持Hysteria2、Tuic"
  2634. echoContent yellow "端口跳跃的起始位置为30000"
  2635. echoContent yellow "端口跳跃的结束位置为40000"
  2636. echoContent yellow "可以在30000-40000范围中选一段"
  2637. echoContent yellow "建议1000个左右"
  2638. echoContent yellow "注意不要和其他的端口跳跃设置范围一样,设置相同会覆盖。"
  2639. echoContent yellow "请输入端口跳跃的范围,例如[30000-31000]"
  2640. read -r -p "范围:" portHoppingRange
  2641. if [[ -z "${portHoppingRange}" ]]; then
  2642. echoContent red " ---> 范围不可为空"
  2643. addPortHopping "${type}" "${targetPort}"
  2644. elif echo "${portHoppingRange}" | grep -q "-"; then
  2645. local portStart=
  2646. local portEnd=
  2647. portStart=$(echo "${portHoppingRange}" | awk -F '-' '{print $1}')
  2648. portEnd=$(echo "${portHoppingRange}" | awk -F '-' '{print $2}')
  2649. if [[ -z "${portStart}" || -z "${portEnd}" ]]; then
  2650. echoContent red " ---> 范围不合法"
  2651. addPortHopping "${type}" "${targetPort}"
  2652. elif ((portStart < 30000 || portStart > 40000 || portEnd < 30000 || portEnd > 40000 || portEnd < portStart)); then
  2653. echoContent red " ---> 范围不合法"
  2654. addPortHopping "${type}" "${targetPort}"
  2655. else
  2656. echoContent green "\n端口范围: ${portHoppingRange}\n"
  2657. if [[ "${release}" == "centos" ]]; then
  2658. sudo firewall-cmd --permanent --add-masquerade
  2659. sudo firewall-cmd --reload
  2660. addFirewalldPortHopping "${portStart}" "${portEnd}" "${targetPort}"
  2661. if ! sudo firewall-cmd --list-forward-ports | grep -q "toport=${targetPort}"; then
  2662. echoContent red " ---> 端口跳跃添加失败"
  2663. exit 0
  2664. fi
  2665. else
  2666. iptables -t nat -A PREROUTING -p udp --dport "${portStart}:${portEnd}" -m comment --comment "mack-a_${type}_portHopping" -j DNAT --to-destination ":${targetPort}"
  2667. sudo netfilter-persistent save
  2668. if ! iptables-save | grep -q "mack-a_${type}_portHopping"; then
  2669. echoContent red " ---> 端口跳跃添加失败"
  2670. exit 0
  2671. fi
  2672. fi
  2673. allowPort "${portStart}:${portEnd}" udp
  2674. echoContent green " ---> 端口跳跃添加成功"
  2675. fi
  2676. fi
  2677. }
  2678. # 读取端口跳跃的配置
  2679. readPortHopping() {
  2680. local type=$1
  2681. local targetPort=$2
  2682. local portHoppingStart=
  2683. local portHoppingEnd=
  2684. if [[ "${release}" == "centos" ]]; then
  2685. portHoppingStart=$(sudo firewall-cmd --list-forward-ports | grep "toport=${targetPort}" | head -1 | cut -d ":" -f 1 | cut -d "=" -f 2)
  2686. portHoppingEnd=$(sudo firewall-cmd --list-forward-ports | grep "toport=${targetPort}" | tail -n 1 | cut -d ":" -f 1 | cut -d "=" -f 2)
  2687. else
  2688. if iptables-save | grep -q "mack-a_${type}_portHopping"; then
  2689. local portHopping=
  2690. portHopping=$(iptables-save | grep "mack-a_${type}_portHopping" | cut -d " " -f 8)
  2691. portHoppingStart=$(echo "${portHopping}" | cut -d ":" -f 1)
  2692. portHoppingEnd=$(echo "${portHopping}" | cut -d ":" -f 2)
  2693. fi
  2694. fi
  2695. if [[ "${type}" == "hysteria2" ]]; then
  2696. hysteria2PortHoppingStart="${portHoppingStart}"
  2697. hysteria2PortHoppingEnd=${portHoppingEnd}
  2698. hysteria2PortHopping="${portHoppingStart}-${portHoppingEnd}"
  2699. elif [[ "${type}" == "tuic" ]]; then
  2700. tuicPortHoppingStart="${portHoppingStart}"
  2701. tuicPortHoppingEnd="${portHoppingEnd}"
  2702. # tuicPortHopping="${portHoppingStart}-${portHoppingEnd}"
  2703. fi
  2704. }
  2705. # 删除端口跳跃iptables规则
  2706. deletePortHoppingRules() {
  2707. local type=$1
  2708. local start=$2
  2709. local end=$3
  2710. local targetPort=$4
  2711. if [[ "${release}" == "centos" ]]; then
  2712. for port in $(seq "${start}" "${end}"); do
  2713. sudo firewall-cmd --permanent --remove-forward-port=port="${port}":proto=udp:toport="${targetPort}"
  2714. done
  2715. sudo firewall-cmd --reload
  2716. else
  2717. iptables -t nat -L PREROUTING --line-numbers | grep "mack-a_${type}_portHopping" | awk '{print $1}' | while read -r line; do
  2718. iptables -t nat -D PREROUTING 1
  2719. sudo netfilter-persistent save
  2720. done
  2721. fi
  2722. }
  2723. # 端口跳跃菜单
  2724. portHoppingMenu() {
  2725. local type=$1
  2726. # 判断iptables是否存在
  2727. if ! find /usr/bin /usr/sbin | grep -q -w iptables; then
  2728. echoContent red " ---> 无法识别iptables工具,无法使用端口跳跃,退出安装"
  2729. exit 0
  2730. fi
  2731. local targetPort=
  2732. local portHoppingStart=
  2733. local portHoppingEnd=
  2734. if [[ "${type}" == "hysteria2" ]]; then
  2735. readPortHopping "${type}" "${singBoxHysteria2Port}"
  2736. targetPort=${singBoxHysteria2Port}
  2737. portHoppingStart=${hysteria2PortHoppingStart}
  2738. portHoppingEnd=${hysteria2PortHoppingEnd}
  2739. elif [[ "${type}" == "tuic" ]]; then
  2740. readPortHopping "${type}" "${singBoxTuicPort}"
  2741. targetPort=${singBoxTuicPort}
  2742. portHoppingStart=${tuicPortHoppingStart}
  2743. portHoppingEnd=${tuicPortHoppingEnd}
  2744. fi
  2745. echoContent skyBlue "\n进度 1/1 : 端口跳跃"
  2746. echoContent red "\n=============================================================="
  2747. echoContent yellow "1.添加端口跳跃"
  2748. echoContent yellow "2.删除端口跳跃"
  2749. echoContent yellow "3.查看端口跳跃"
  2750. read -r -p "请选择:" selectPortHoppingStatus
  2751. if [[ "${selectPortHoppingStatus}" == "1" ]]; then
  2752. addPortHopping "${type}" "${targetPort}"
  2753. elif [[ "${selectPortHoppingStatus}" == "2" ]]; then
  2754. deletePortHoppingRules "${type}" "${portHoppingStart}" "${portHoppingEnd}" "${targetPort}"
  2755. echoContent green " ---> 删除成功"
  2756. elif [[ "${selectPortHoppingStatus}" == "3" ]]; then
  2757. if [[ -n "${portHoppingStart}" && -n "${portHoppingEnd}" ]]; then
  2758. echoContent green " ---> 当前端口跳跃范围为: ${portHoppingStart}-${portHoppingEnd}"
  2759. else
  2760. echoContent yellow " ---> 未设置端口跳跃"
  2761. fi
  2762. else
  2763. portHoppingMenu
  2764. fi
  2765. }
  2766. # 初始化tuic端口
  2767. initTuicPort() {
  2768. readSingBoxConfig
  2769. if [[ -n "${tuicPort}" ]]; then
  2770. read -r -p "读取到上次安装时的端口,是否使用上次安装时的端口?[y/n]:" historyTuicPortStatus
  2771. if [[ "${historyTuicPortStatus}" == "y" ]]; then
  2772. echoContent yellow "\n ---> 端口: ${tuicPort}"
  2773. else
  2774. tuicPort=
  2775. fi
  2776. fi
  2777. if [[ -z "${tuicPort}" ]]; then
  2778. echoContent yellow "请输入Tuic端口[回车随机10000-30000],不可与其他服务重复"
  2779. read -r -p "端口:" tuicPort
  2780. if [[ -z "${tuicPort}" ]]; then
  2781. tuicPort=$((RANDOM % 20001 + 10000))
  2782. fi
  2783. fi
  2784. if [[ -z ${tuicPort} ]]; then
  2785. echoContent red " ---> 端口不可为空"
  2786. initTuicPort "$2"
  2787. elif ((tuicPort < 1 || tuicPort > 65535)); then
  2788. echoContent red " ---> 端口不合法"
  2789. initTuicPort "$2"
  2790. fi
  2791. echoContent green "\n ---> 端口: ${tuicPort}"
  2792. allowPort "${tuicPort}"
  2793. allowPort "${tuicPort}" "udp"
  2794. }
  2795. # 初始化tuic的协议
  2796. initTuicProtocol() {
  2797. if [[ -n "${tuicAlgorithm}" && -z "${lastInstallationConfig}" ]]; then
  2798. read -r -p "读取到上次使用的算法,是否使用 ?[y/n]:" historyTuicAlgorithm
  2799. if [[ "${historyTuicAlgorithm}" != "y" ]]; then
  2800. tuicAlgorithm=
  2801. else
  2802. echoContent yellow "\n ---> 算法: ${tuicAlgorithm}\n"
  2803. fi
  2804. elif [[ -n "${tuicAlgorithm}" && -n "${lastInstallationConfig}" ]]; then
  2805. echoContent yellow "\n ---> 算法: ${tuicAlgorithm}\n"
  2806. fi
  2807. if [[ -z "${tuicAlgorithm}" ]]; then
  2808. echoContent skyBlue "\n请选择算法类型"
  2809. echoContent red "=============================================================="
  2810. echoContent yellow "1.bbr(默认)"
  2811. echoContent yellow "2.cubic"
  2812. echoContent yellow "3.new_reno"
  2813. echoContent red "=============================================================="
  2814. read -r -p "请选择:" selectTuicAlgorithm
  2815. case ${selectTuicAlgorithm} in
  2816. 1)
  2817. tuicAlgorithm="bbr"
  2818. ;;
  2819. 2)
  2820. tuicAlgorithm="cubic"
  2821. ;;
  2822. 3)
  2823. tuicAlgorithm="new_reno"
  2824. ;;
  2825. *)
  2826. tuicAlgorithm="bbr"
  2827. ;;
  2828. esac
  2829. echoContent yellow "\n ---> 算法: ${tuicAlgorithm}\n"
  2830. fi
  2831. }
  2832. # 初始化tuic配置
  2833. #initTuicConfig() {
  2834. # echoContent skyBlue "\n进度 $1/${totalProgress} : 初始化Tuic配置"
  2835. #
  2836. # initTuicPort
  2837. # initTuicProtocol
  2838. # cat <<EOF >/etc/v2ray-agent/tuic/conf/config.json
  2839. #{
  2840. # "server": "[::]:${tuicPort}",
  2841. # "users": $(initXrayClients 9),
  2842. # "certificate": "/etc/v2ray-agent/tls/${currentHost}.crt",
  2843. # "private_key": "/etc/v2ray-agent/tls/${currentHost}.key",
  2844. # "congestion_control":"${tuicAlgorithm}",
  2845. # "alpn": ["h3"],
  2846. # "log_level": "warn"
  2847. #}
  2848. #EOF
  2849. #}
  2850. # 初始化singbox route配置
  2851. initSingBoxRouteConfig() {
  2852. downloadSingBoxGeositeDB
  2853. local outboundTag=$1
  2854. if [[ ! -f "${singBoxConfigPath}${outboundTag}_route.json" ]]; then
  2855. cat <<EOF >"${singBoxConfigPath}${outboundTag}_route.json"
  2856. {
  2857. "route": {
  2858. "geosite": {
  2859. "path": "${singBoxConfigPath}geosite.db"
  2860. },
  2861. "rules": [
  2862. {
  2863. "domain": [
  2864. ],
  2865. "geosite": [
  2866. ],
  2867. "outbound": "${outboundTag}"
  2868. }
  2869. ]
  2870. }
  2871. }
  2872. EOF
  2873. fi
  2874. }
  2875. # 下载sing-box geosite db
  2876. downloadSingBoxGeositeDB() {
  2877. if [[ ! -f "${singBoxConfigPath}geosite.db" ]]; then
  2878. if [[ "${release}" == "alpine" ]]; then
  2879. wget -q -P "${singBoxConfigPath}" https://github.com/Johnshall/sing-geosite/releases/latest/download/geosite.db
  2880. else
  2881. wget -q "${wgetShowProgressStatus}" -P "${singBoxConfigPath}" https://github.com/Johnshall/sing-geosite/releases/latest/download/geosite.db
  2882. fi
  2883. fi
  2884. }
  2885. # 添加sing-box路由规则
  2886. addSingBoxRouteRule() {
  2887. local outboundTag=$1
  2888. # 域名列表
  2889. local domainList=$2
  2890. # 路由文件名称
  2891. local routingName=$3
  2892. # 读取上次安装内容
  2893. if [[ -f "${singBoxConfigPath}${routingName}.json" ]]; then
  2894. read -r -p "读取到上次的配置,是否保留 ?[y/n]:" historyRouteStatus
  2895. if [[ "${historyRouteStatus}" == "y" ]]; then
  2896. domainList="${domainList},$(jq -rc .route.rules[0].rule_set[] "${singBoxConfigPath}${routingName}.json" | awk -F "[_]" '{print $1}' | paste -sd ',')"
  2897. domainList="${domainList},$(jq -rc .route.rules[0].domain_regex[] "${singBoxConfigPath}${routingName}.json" | awk -F "[*]" '{print $2}' | paste -sd ',' | sed 's/\\//g')"
  2898. fi
  2899. fi
  2900. local rules=
  2901. rules=$(initSingBoxRules "${domainList}" "${routingName}")
  2902. # domain精确匹配规则
  2903. local domainRules=
  2904. domainRules=$(echo "${rules}" | jq .domainRules)
  2905. # ruleSet规则集
  2906. local ruleSet=
  2907. ruleSet=$(echo "${rules}" | jq .ruleSet)
  2908. # ruleSet规则tag
  2909. local ruleSetTag=[]
  2910. if [[ "$(echo "${ruleSet}" | jq '.|length')" != "0" ]]; then
  2911. ruleSetTag=$(echo "${ruleSet}" | jq '.|map(.tag)')
  2912. fi
  2913. if [[ -n "${singBoxConfigPath}" ]]; then
  2914. cat <<EOF >"${singBoxConfigPath}${routingName}.json"
  2915. {
  2916. "route": {
  2917. "rules": [
  2918. {
  2919. "rule_set":${ruleSetTag},
  2920. "domain_regex":${domainRules},
  2921. "outbound": "${outboundTag}"
  2922. }
  2923. ],
  2924. "rule_set":${ruleSet}
  2925. }
  2926. }
  2927. EOF
  2928. jq 'if .route.rule_set == [] then del(.route.rule_set) else . end' "${singBoxConfigPath}${routingName}.json" >"${singBoxConfigPath}${routingName}_tmp.json" && mv "${singBoxConfigPath}${routingName}_tmp.json" "${singBoxConfigPath}${routingName}.json"
  2929. fi
  2930. }
  2931. # 移除sing-box route rule
  2932. removeSingBoxRouteRule() {
  2933. local outboundTag=$1
  2934. local delRules
  2935. if [[ -f "${singBoxConfigPath}${outboundTag}_route.json" ]]; then
  2936. delRules=$(jq -r 'del(.route.rules[]|select(.outbound=="'"${outboundTag}"'"))' "${singBoxConfigPath}${outboundTag}_route.json")
  2937. echo "${delRules}" >"${singBoxConfigPath}${outboundTag}_route.json"
  2938. fi
  2939. }
  2940. # 添加sing-box出站
  2941. addSingBoxOutbound() {
  2942. local tag=$1
  2943. local type="ipv4"
  2944. local detour=$2
  2945. if echo "${tag}" | grep -q "IPv6"; then
  2946. type=ipv6
  2947. fi
  2948. if [[ -n "${detour}" ]]; then
  2949. cat <<EOF >"${singBoxConfigPath}${tag}.json"
  2950. {
  2951. "outbounds": [
  2952. {
  2953. "type": "direct",
  2954. "tag": "${tag}",
  2955. "detour": "${detour}",
  2956. "domain_strategy": "${type}_only"
  2957. }
  2958. ]
  2959. }
  2960. EOF
  2961. elif echo "${tag}" | grep -q "direct"; then
  2962. cat <<EOF >"${singBoxConfigPath}${tag}.json"
  2963. {
  2964. "outbounds": [
  2965. {
  2966. "type": "direct",
  2967. "tag": "${tag}"
  2968. }
  2969. ]
  2970. }
  2971. EOF
  2972. elif echo "${tag}" | grep -q "block"; then
  2973. cat <<EOF >"${singBoxConfigPath}${tag}.json"
  2974. {
  2975. "outbounds": [
  2976. {
  2977. "type": "block",
  2978. "tag": "${tag}"
  2979. }
  2980. ]
  2981. }
  2982. EOF
  2983. else
  2984. cat <<EOF >"${singBoxConfigPath}${tag}.json"
  2985. {
  2986. "outbounds": [
  2987. {
  2988. "type": "direct",
  2989. "tag": "${tag}",
  2990. "domain_strategy": "${type}_only"
  2991. }
  2992. ]
  2993. }
  2994. EOF
  2995. fi
  2996. }
  2997. # 添加Xray-core 出站
  2998. addXrayOutbound() {
  2999. local tag=$1
  3000. local domainStrategy=
  3001. if echo "${tag}" | grep -q "IPv4"; then
  3002. domainStrategy="ForceIPv4"
  3003. elif echo "${tag}" | grep -q "IPv6"; then
  3004. domainStrategy="ForceIPv6"
  3005. fi
  3006. if [[ -n "${domainStrategy}" ]]; then
  3007. cat <<EOF >"/etc/v2ray-agent/xray/conf/${tag}.json"
  3008. {
  3009. "outbounds":[
  3010. {
  3011. "protocol":"freedom",
  3012. "settings":{
  3013. "domainStrategy":"${domainStrategy}"
  3014. },
  3015. "tag":"${tag}"
  3016. }
  3017. ]
  3018. }
  3019. EOF
  3020. fi
  3021. # direct
  3022. if echo "${tag}" | grep -q "direct"; then
  3023. cat <<EOF >"/etc/v2ray-agent/xray/conf/${tag}.json"
  3024. {
  3025. "outbounds":[
  3026. {
  3027. "protocol":"freedom",
  3028. "settings": {
  3029. "domainStrategy":"UseIP"
  3030. },
  3031. "tag":"${tag}"
  3032. }
  3033. ]
  3034. }
  3035. EOF
  3036. fi
  3037. # blackhole
  3038. if echo "${tag}" | grep -q "blackhole"; then
  3039. cat <<EOF >"/etc/v2ray-agent/xray/conf/${tag}.json"
  3040. {
  3041. "outbounds":[
  3042. {
  3043. "protocol":"blackhole",
  3044. "tag":"${tag}"
  3045. }
  3046. ]
  3047. }
  3048. EOF
  3049. fi
  3050. # socks5 outbound
  3051. if echo "${tag}" | grep -q "socks5"; then
  3052. cat <<EOF >"/etc/v2ray-agent/xray/conf/${tag}.json"
  3053. {
  3054. "outbounds": [
  3055. {
  3056. "protocol": "socks",
  3057. "tag": "${tag}",
  3058. "settings": {
  3059. "servers": [
  3060. {
  3061. "address": "${socks5RoutingOutboundIP}",
  3062. "port": ${socks5RoutingOutboundPort},
  3063. "users": [
  3064. {
  3065. "user": "${socks5RoutingOutboundUserName}",
  3066. "pass": "${socks5RoutingOutboundPassword}"
  3067. }
  3068. ]
  3069. }
  3070. ]
  3071. }
  3072. }
  3073. ]
  3074. }
  3075. EOF
  3076. fi
  3077. if echo "${tag}" | grep -q "wireguard_out_IPv4"; then
  3078. cat <<EOF >"/etc/v2ray-agent/xray/conf/${tag}.json"
  3079. {
  3080. "outbounds": [
  3081. {
  3082. "protocol": "wireguard",
  3083. "settings": {
  3084. "secretKey": "${secretKeyWarpReg}",
  3085. "address": [
  3086. "${address}"
  3087. ],
  3088. "peers": [
  3089. {
  3090. "publicKey": "${publicKeyWarpReg}",
  3091. "allowedIPs": [
  3092. "0.0.0.0/0",
  3093. "::/0"
  3094. ],
  3095. "endpoint": "162.159.192.1:2408"
  3096. }
  3097. ],
  3098. "reserved": ${reservedWarpReg},
  3099. "mtu": 1280
  3100. },
  3101. "tag": "${tag}"
  3102. }
  3103. ]
  3104. }
  3105. EOF
  3106. fi
  3107. if echo "${tag}" | grep -q "wireguard_out_IPv6"; then
  3108. cat <<EOF >"/etc/v2ray-agent/xray/conf/${tag}.json"
  3109. {
  3110. "outbounds": [
  3111. {
  3112. "protocol": "wireguard",
  3113. "settings": {
  3114. "secretKey": "${secretKeyWarpReg}",
  3115. "address": [
  3116. "${address}"
  3117. ],
  3118. "peers": [
  3119. {
  3120. "publicKey": "${publicKeyWarpReg}",
  3121. "allowedIPs": [
  3122. "0.0.0.0/0",
  3123. "::/0"
  3124. ],
  3125. "endpoint": "162.159.192.1:2408"
  3126. }
  3127. ],
  3128. "reserved": ${reservedWarpReg},
  3129. "mtu": 1280
  3130. },
  3131. "tag": "${tag}"
  3132. }
  3133. ]
  3134. }
  3135. EOF
  3136. fi
  3137. if echo "${tag}" | grep -q "vmess-out"; then
  3138. cat <<EOF >"/etc/v2ray-agent/xray/conf/${tag}.json"
  3139. {
  3140. "outbounds": [
  3141. {
  3142. "tag": "${tag}",
  3143. "protocol": "vmess",
  3144. "streamSettings": {
  3145. "network": "ws",
  3146. "security": "tls",
  3147. "tlsSettings": {
  3148. "allowInsecure": false
  3149. },
  3150. "wsSettings": {
  3151. "path": "${setVMessWSTLSPath}"
  3152. }
  3153. },
  3154. "mux": {
  3155. "enabled": true,
  3156. "concurrency": 8
  3157. },
  3158. "settings": {
  3159. "vnext": [
  3160. {
  3161. "address": "${setVMessWSTLSAddress}",
  3162. "port": "${setVMessWSTLSPort}",
  3163. "users": [
  3164. {
  3165. "id": "${setVMessWSTLSUUID}",
  3166. "security": "auto",
  3167. "alterId": 0
  3168. }
  3169. ]
  3170. }
  3171. ]
  3172. }
  3173. }
  3174. ]
  3175. }
  3176. EOF
  3177. fi
  3178. }
  3179. # 删除 Xray-core出站
  3180. removeXrayOutbound() {
  3181. local tag=$1
  3182. if [[ -f "/etc/v2ray-agent/xray/conf/${tag}.json" ]]; then
  3183. rm "/etc/v2ray-agent/xray/conf/${tag}.json" >/dev/null 2>&1
  3184. fi
  3185. }
  3186. # 移除sing-box配置
  3187. removeSingBoxConfig() {
  3188. local tag=$1
  3189. if [[ -f "${singBoxConfigPath}${tag}.json" ]]; then
  3190. rm "${singBoxConfigPath}${tag}.json"
  3191. fi
  3192. }
  3193. # 初始化wireguard出站信息
  3194. addSingBoxWireGuardEndpoints() {
  3195. local type=$1
  3196. readConfigWarpReg
  3197. cat <<EOF >"${singBoxConfigPath}wireguard_endpoints_${type}.json"
  3198. {
  3199. "endpoints": [
  3200. {
  3201. "type": "wireguard",
  3202. "tag": "wireguard_endpoints_${type}",
  3203. "address": [
  3204. "${address}"
  3205. ],
  3206. "private_key": "${secretKeyWarpReg}",
  3207. "peers": [
  3208. {
  3209. "address": "162.159.192.1",
  3210. "port": 2408,
  3211. "public_key": "${publicKeyWarpReg}",
  3212. "reserved":${reservedWarpReg},
  3213. "allowed_ips": ["0.0.0.0/0","::/0"]
  3214. }
  3215. ]
  3216. }
  3217. ]
  3218. }
  3219. EOF
  3220. }
  3221. # 初始化 sing-box Hysteria2 配置
  3222. initSingBoxHysteria2Config() {
  3223. echoContent skyBlue "\n进度 $1/${totalProgress} : 初始化Hysteria2配置"
  3224. initHysteriaPort
  3225. initHysteria2Network
  3226. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/hysteria2.json
  3227. {
  3228. "inbounds": [
  3229. {
  3230. "type": "hysteria2",
  3231. "listen": "::",
  3232. "listen_port": ${hysteriaPort},
  3233. "users": $(initXrayClients 6),
  3234. "up_mbps":${hysteria2ClientDownloadSpeed},
  3235. "down_mbps":${hysteria2ClientUploadSpeed},
  3236. "tls": {
  3237. "enabled": true,
  3238. "server_name":"${currentHost}",
  3239. "alpn": [
  3240. "h3"
  3241. ],
  3242. "certificate_path": "/etc/v2ray-agent/tls/${currentHost}.crt",
  3243. "key_path": "/etc/v2ray-agent/tls/${currentHost}.key"
  3244. }
  3245. }
  3246. ]
  3247. }
  3248. EOF
  3249. }
  3250. # sing-box Tuic安装
  3251. singBoxTuicInstall() {
  3252. if ! echo "${currentInstallProtocolType}" | grep -qE ",0,|,1,|,2,|,3,|,4,|,5,|,6,|,9,|,10,"; then
  3253. echoContent red "\n ---> 由于需要依赖证书,如安装Tuic,请先安装带有TLS标识协议"
  3254. exit 0
  3255. fi
  3256. totalProgress=5
  3257. installSingBox 1
  3258. selectCustomInstallType=",9,"
  3259. initSingBoxConfig custom 2 true
  3260. installSingBoxService 3
  3261. reloadCore
  3262. showAccounts 4
  3263. }
  3264. # sing-box hy2安装
  3265. singBoxHysteria2Install() {
  3266. if ! echo "${currentInstallProtocolType}" | grep -qE ",0,|,1,|,2,|,3,|,4,|,5,|,6,|,9,|,10,"; then
  3267. echoContent red "\n ---> 由于需要依赖证书,如安装Hysteria2,请先安装带有TLS标识协议"
  3268. exit 0
  3269. fi
  3270. totalProgress=5
  3271. installSingBox 1
  3272. selectCustomInstallType=",6,"
  3273. initSingBoxConfig custom 2 true
  3274. installSingBoxService 3
  3275. reloadCore
  3276. showAccounts 4
  3277. }
  3278. # 合并config
  3279. singBoxMergeConfig() {
  3280. rm /etc/v2ray-agent/sing-box/conf/config.json >/dev/null 2>&1
  3281. /etc/v2ray-agent/sing-box/sing-box merge config.json -C /etc/v2ray-agent/sing-box/conf/config/ -D /etc/v2ray-agent/sing-box/conf/ >/dev/null 2>&1
  3282. }
  3283. # 初始化Xray Trojan XTLS 配置文件
  3284. #initXrayFrontingConfig() {
  3285. # echoContent red " ---> Trojan暂不支持 xtls-rprx-vision"
  3286. # if [[ -z "${configPath}" ]]; then
  3287. # echoContent red " ---> 未安装,请使用脚本安装"
  3288. # menu
  3289. # exit 0
  3290. # fi
  3291. # if [[ "${coreInstallType}" != "1" ]]; then
  3292. # echoContent red " ---> 未安装可用类型"
  3293. # fi
  3294. # local xtlsType=
  3295. # if echo ${currentInstallProtocolType} | grep -q trojan; then
  3296. # xtlsType=VLESS
  3297. # else
  3298. # xtlsType=Trojan
  3299. # fi
  3300. #
  3301. # echoContent skyBlue "\n功能 1/${totalProgress} : 前置切换为${xtlsType}"
  3302. # echoContent red "\n=============================================================="
  3303. # echoContent yellow "# 注意事项\n"
  3304. # echoContent yellow "会将前置替换为${xtlsType}"
  3305. # echoContent yellow "如果前置是Trojan,查看账号时则会出现两个Trojan协议的节点,有一个不可用xtls"
  3306. # echoContent yellow "再次执行可切换至上一次的前置\n"
  3307. #
  3308. # echoContent yellow "1.切换至${xtlsType}"
  3309. # echoContent red "=============================================================="
  3310. # read -r -p "请选择:" selectType
  3311. # if [[ "${selectType}" == "1" ]]; then
  3312. #
  3313. # if [[ "${xtlsType}" == "Trojan" ]]; then
  3314. #
  3315. # local VLESSConfig
  3316. # VLESSConfig=$(cat ${configPath}${frontingType}.json)
  3317. # VLESSConfig=${VLESSConfig//"id"/"password"}
  3318. # VLESSConfig=${VLESSConfig//VLESSTCP/TrojanTCPXTLS}
  3319. # VLESSConfig=${VLESSConfig//VLESS/Trojan}
  3320. # VLESSConfig=${VLESSConfig//"vless"/"trojan"}
  3321. # VLESSConfig=${VLESSConfig//"id"/"password"}
  3322. #
  3323. # echo "${VLESSConfig}" | jq . >${configPath}02_trojan_TCP_inbounds.json
  3324. # rm ${configPath}${frontingType}.json
  3325. # elif [[ "${xtlsType}" == "VLESS" ]]; then
  3326. #
  3327. # local VLESSConfig
  3328. # VLESSConfig=$(cat ${configPath}02_trojan_TCP_inbounds.json)
  3329. # VLESSConfig=${VLESSConfig//"password"/"id"}
  3330. # VLESSConfig=${VLESSConfig//TrojanTCPXTLS/VLESSTCP}
  3331. # VLESSConfig=${VLESSConfig//Trojan/VLESS}
  3332. # VLESSConfig=${VLESSConfig//"trojan"/"vless"}
  3333. # VLESSConfig=${VLESSConfig//"password"/"id"}
  3334. #
  3335. # echo "${VLESSConfig}" | jq . >${configPath}02_VLESS_TCP_inbounds.json
  3336. # rm ${configPath}02_trojan_TCP_inbounds.json
  3337. # fi
  3338. # reloadCore
  3339. # fi
  3340. #
  3341. # exit 0
  3342. #}
  3343. # 初始化sing-box端口
  3344. initSingBoxPort() {
  3345. local port=$1
  3346. if [[ -n "${port}" && -z "${lastInstallationConfig}" ]]; then
  3347. read -r -p "读取到上次使用的端口,是否使用 ?[y/n]:" historyPort
  3348. if [[ "${historyPort}" != "y" ]]; then
  3349. port=
  3350. else
  3351. echo "${port}"
  3352. fi
  3353. elif [[ -n "${port}" && -n "${lastInstallationConfig}" ]]; then
  3354. echo "${port}"
  3355. fi
  3356. if [[ -z "${port}" ]]; then
  3357. read -r -p '请输入自定义端口[需合法],端口不可重复,[回车]随机端口:' port
  3358. if [[ -z "${port}" ]]; then
  3359. port=$((RANDOM % 50001 + 10000))
  3360. fi
  3361. if ((port >= 1 && port <= 65535)); then
  3362. allowPort "${port}"
  3363. allowPort "${port}" "udp"
  3364. echo "${port}"
  3365. else
  3366. echoContent red " ---> 端口输入错误"
  3367. exit 0
  3368. fi
  3369. fi
  3370. }
  3371. # 初始化Xray 配置文件
  3372. initXrayConfig() {
  3373. echoContent skyBlue "\n进度 $2/${totalProgress} : 初始化Xray配置"
  3374. echo
  3375. local uuid=
  3376. local addClientsStatus=
  3377. if [[ -n "${currentUUID}" && -z "${lastInstallationConfig}" ]]; then
  3378. read -r -p "读取到上次用户配置,是否使用上次安装的配置 ?[y/n]:" historyUUIDStatus
  3379. if [[ "${historyUUIDStatus}" == "y" ]]; then
  3380. addClientsStatus=true
  3381. echoContent green "\n ---> 使用成功"
  3382. fi
  3383. elif [[ -n "${currentUUID}" && -n "${lastInstallationConfig}" ]]; then
  3384. addClientsStatus=true
  3385. fi
  3386. if [[ -z "${addClientsStatus}" ]]; then
  3387. echoContent yellow "请输入自定义UUID[需合法],[回车]随机UUID"
  3388. read -r -p 'UUID:' customUUID
  3389. if [[ -n ${customUUID} ]]; then
  3390. uuid=${customUUID}
  3391. else
  3392. uuid=$(/etc/v2ray-agent/xray/xray uuid)
  3393. fi
  3394. echoContent yellow "\n请输入自定义用户名[需合法],[回车]随机用户名"
  3395. read -r -p '用户名:' customEmail
  3396. if [[ -z ${customEmail} ]]; then
  3397. customEmail="$(echo "${uuid}" | cut -d "-" -f 1)-VLESS_TCP/TLS_Vision"
  3398. fi
  3399. fi
  3400. if [[ -z "${addClientsStatus}" && -z "${uuid}" ]]; then
  3401. addClientsStatus=
  3402. echoContent red "\n ---> uuid读取错误,随机生成"
  3403. uuid=$(/etc/v2ray-agent/xray/xray uuid)
  3404. fi
  3405. if [[ -n "${uuid}" ]]; then
  3406. currentClients='[{"id":"'${uuid}'","add":"'${add}'","flow":"xtls-rprx-vision","email":"'${customEmail}'"}]'
  3407. echoContent green "\n ${customEmail}:${uuid}"
  3408. echo
  3409. fi
  3410. # log
  3411. if [[ ! -f "/etc/v2ray-agent/xray/conf/00_log.json" ]]; then
  3412. cat <<EOF >/etc/v2ray-agent/xray/conf/00_log.json
  3413. {
  3414. "log": {
  3415. "error": "/etc/v2ray-agent/xray/error.log",
  3416. "loglevel": "warning",
  3417. "dnsLog": false
  3418. }
  3419. }
  3420. EOF
  3421. fi
  3422. if [[ ! -f "/etc/v2ray-agent/xray/conf/12_policy.json" ]]; then
  3423. cat <<EOF >/etc/v2ray-agent/xray/conf/12_policy.json
  3424. {
  3425. "policy": {
  3426. "levels": {
  3427. "0": {
  3428. "handshake": $((1 + RANDOM % 4)),
  3429. "connIdle": $((250 + RANDOM % 51))
  3430. }
  3431. }
  3432. }
  3433. }
  3434. EOF
  3435. fi
  3436. addXrayOutbound "z_direct_outbound"
  3437. # dns
  3438. if [[ ! -f "/etc/v2ray-agent/xray/conf/11_dns.json" ]]; then
  3439. cat <<EOF >/etc/v2ray-agent/xray/conf/11_dns.json
  3440. {
  3441. "dns": {
  3442. "servers": [
  3443. "localhost"
  3444. ]
  3445. }
  3446. }
  3447. EOF
  3448. fi
  3449. # routing
  3450. cat <<EOF >/etc/v2ray-agent/xray/conf/09_routing.json
  3451. {
  3452. "routing": {
  3453. "rules": [
  3454. {
  3455. "type": "field",
  3456. "domain": [
  3457. "domain:gstatic.com",
  3458. "domain:googleapis.com",
  3459. "domain:googleapis.cn"
  3460. ],
  3461. "outboundTag": "z_direct_outbound"
  3462. }
  3463. ]
  3464. }
  3465. }
  3466. EOF
  3467. # VLESS_TCP_TLS_Vision
  3468. # 回落nginx
  3469. local fallbacksList='{"dest":31300,"xver":1},{"alpn":"h2","dest":31302,"xver":1}'
  3470. # trojan
  3471. if echo "${selectCustomInstallType}" | grep -q ",4," || [[ "$1" == "all" ]]; then
  3472. fallbacksList='{"dest":31296,"xver":1},{"alpn":"h2","dest":31302,"xver":1}'
  3473. cat <<EOF >/etc/v2ray-agent/xray/conf/04_trojan_TCP_inbounds.json
  3474. {
  3475. "inbounds":[
  3476. {
  3477. "port": 31296,
  3478. "listen": "127.0.0.1",
  3479. "protocol": "trojan",
  3480. "tag":"trojanTCP",
  3481. "settings": {
  3482. "clients": $(initXrayClients 4),
  3483. "fallbacks":[
  3484. {
  3485. "dest":"31300",
  3486. "xver":1
  3487. }
  3488. ]
  3489. },
  3490. "streamSettings": {
  3491. "network": "tcp",
  3492. "security": "none",
  3493. "tcpSettings": {
  3494. "acceptProxyProtocol": true
  3495. }
  3496. }
  3497. }
  3498. ]
  3499. }
  3500. EOF
  3501. elif [[ -z "$3" ]]; then
  3502. rm /etc/v2ray-agent/xray/conf/04_trojan_TCP_inbounds.json >/dev/null 2>&1
  3503. fi
  3504. # VLESS_WS_TLS
  3505. if echo "${selectCustomInstallType}" | grep -q ",1," || [[ "$1" == "all" ]]; then
  3506. fallbacksList=${fallbacksList}',{"path":"/'${customPath}'ws","dest":31297,"xver":1}'
  3507. cat <<EOF >/etc/v2ray-agent/xray/conf/03_VLESS_WS_inbounds.json
  3508. {
  3509. "inbounds":[
  3510. {
  3511. "port": 31297,
  3512. "listen": "127.0.0.1",
  3513. "protocol": "vless",
  3514. "tag":"VLESSWS",
  3515. "settings": {
  3516. "clients": $(initXrayClients 1),
  3517. "decryption": "none"
  3518. },
  3519. "streamSettings": {
  3520. "network": "ws",
  3521. "security": "none",
  3522. "wsSettings": {
  3523. "acceptProxyProtocol": true,
  3524. "path": "/${customPath}ws"
  3525. }
  3526. }
  3527. }
  3528. ]
  3529. }
  3530. EOF
  3531. elif [[ -z "$3" ]]; then
  3532. rm /etc/v2ray-agent/xray/conf/03_VLESS_WS_inbounds.json >/dev/null 2>&1
  3533. fi
  3534. # VLESS_XHTTP_TLS
  3535. if echo "${selectCustomInstallType}" | grep -q ",12," || [[ "$1" == "all" ]]; then
  3536. initXrayXHTTPort
  3537. initRealityClientServersName
  3538. initRealityKey
  3539. initRealityMldsa65
  3540. cat <<EOF >/etc/v2ray-agent/xray/conf/12_VLESS_XHTTP_inbounds.json
  3541. {
  3542. "inbounds":[
  3543. {
  3544. "port": ${xHTTPort},
  3545. "listen": "0.0.0.0",
  3546. "protocol": "vless",
  3547. "tag":"VLESSRealityXHTTP",
  3548. "settings": {
  3549. "clients": $(initXrayClients 12),
  3550. "decryption": "none"
  3551. },
  3552. "streamSettings": {
  3553. "network": "xhttp",
  3554. "security": "reality",
  3555. "realitySettings": {
  3556. "show": false,
  3557. "dest": "${realityServerName}:${realityDomainPort}",
  3558. "xver": 0,
  3559. "serverNames": [
  3560. "${realityServerName}"
  3561. ],
  3562. "privateKey": "${realityPrivateKey}",
  3563. "publicKey": "${realityPublicKey}",
  3564. "maxTimeDiff": 70000,
  3565. "shortIds": [
  3566. "",
  3567. "6ba85179e30d4fc2"
  3568. ]
  3569. },
  3570. "xhttpSettings": {
  3571. "host": "${realityServerName}",
  3572. "path": "/${customPath}xHTTP",
  3573. "mode": "auto"
  3574. }
  3575. }
  3576. }
  3577. ]
  3578. }
  3579. EOF
  3580. elif [[ -z "$3" ]]; then
  3581. rm /etc/v2ray-agent/xray/conf/12_VLESS_XHTTP_inbounds.json >/dev/null 2>&1
  3582. fi
  3583. # trojan_grpc
  3584. # if echo "${selectCustomInstallType}" | grep -q ",2," || [[ "$1" == "all" ]]; then
  3585. # if ! echo "${selectCustomInstallType}" | grep -q ",5," && [[ -n ${selectCustomInstallType} ]]; then
  3586. # fallbacksList=${fallbacksList//31302/31304}
  3587. # fi
  3588. # cat <<EOF >/etc/v2ray-agent/xray/conf/04_trojan_gRPC_inbounds.json
  3589. #{
  3590. # "inbounds": [
  3591. # {
  3592. # "port": 31304,
  3593. # "listen": "127.0.0.1",
  3594. # "protocol": "trojan",
  3595. # "tag": "trojangRPCTCP",
  3596. # "settings": {
  3597. # "clients": $(initXrayClients 2),
  3598. # "fallbacks": [
  3599. # {
  3600. # "dest": "31300"
  3601. # }
  3602. # ]
  3603. # },
  3604. # "streamSettings": {
  3605. # "network": "grpc",
  3606. # "grpcSettings": {
  3607. # "serviceName": "${customPath}trojangrpc"
  3608. # }
  3609. # }
  3610. # }
  3611. # ]
  3612. #}
  3613. #EOF
  3614. # elif [[ -z "$3" ]]; then
  3615. # rm /etc/v2ray-agent/xray/conf/04_trojan_gRPC_inbounds.json >/dev/null 2>&1
  3616. # fi
  3617. # VMess_WS
  3618. if echo "${selectCustomInstallType}" | grep -q ",3," || [[ "$1" == "all" ]]; then
  3619. fallbacksList=${fallbacksList}',{"path":"/'${customPath}'vws","dest":31299,"xver":1}'
  3620. cat <<EOF >/etc/v2ray-agent/xray/conf/05_VMess_WS_inbounds.json
  3621. {
  3622. "inbounds":[
  3623. {
  3624. "listen": "127.0.0.1",
  3625. "port": 31299,
  3626. "protocol": "vmess",
  3627. "tag":"VMessWS",
  3628. "settings": {
  3629. "clients": $(initXrayClients 3)
  3630. },
  3631. "streamSettings": {
  3632. "network": "ws",
  3633. "security": "none",
  3634. "wsSettings": {
  3635. "acceptProxyProtocol": true,
  3636. "path": "/${customPath}vws"
  3637. }
  3638. }
  3639. }
  3640. ]
  3641. }
  3642. EOF
  3643. elif [[ -z "$3" ]]; then
  3644. rm /etc/v2ray-agent/xray/conf/05_VMess_WS_inbounds.json >/dev/null 2>&1
  3645. fi
  3646. # VLESS_gRPC
  3647. if echo "${selectCustomInstallType}" | grep -q ",5," || [[ "$1" == "all" ]]; then
  3648. cat <<EOF >/etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json
  3649. {
  3650. "inbounds":[
  3651. {
  3652. "port": 31301,
  3653. "listen": "127.0.0.1",
  3654. "protocol": "vless",
  3655. "tag":"VLESSGRPC",
  3656. "settings": {
  3657. "clients": $(initXrayClients 5),
  3658. "decryption": "none"
  3659. },
  3660. "streamSettings": {
  3661. "network": "grpc",
  3662. "grpcSettings": {
  3663. "serviceName": "${customPath}grpc"
  3664. }
  3665. }
  3666. }
  3667. ]
  3668. }
  3669. EOF
  3670. elif [[ -z "$3" ]]; then
  3671. rm /etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json >/dev/null 2>&1
  3672. fi
  3673. # VLESS Vision
  3674. if echo "${selectCustomInstallType}" | grep -q ",0," || [[ "$1" == "all" ]]; then
  3675. cat <<EOF >/etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json
  3676. {
  3677. "inbounds":[
  3678. {
  3679. "port": ${port},
  3680. "protocol": "vless",
  3681. "tag":"VLESSTCP",
  3682. "settings": {
  3683. "clients":$(initXrayClients 0),
  3684. "decryption": "none",
  3685. "fallbacks": [
  3686. ${fallbacksList}
  3687. ]
  3688. },
  3689. "add": "${add}",
  3690. "streamSettings": {
  3691. "network": "tcp",
  3692. "security": "tls",
  3693. "tlsSettings": {
  3694. "rejectUnknownSni": true,
  3695. "minVersion": "1.2",
  3696. "certificates": [
  3697. {
  3698. "certificateFile": "/etc/v2ray-agent/tls/${domain}.crt",
  3699. "keyFile": "/etc/v2ray-agent/tls/${domain}.key",
  3700. "ocspStapling": 3600
  3701. }
  3702. ]
  3703. }
  3704. }
  3705. }
  3706. ]
  3707. }
  3708. EOF
  3709. elif [[ -z "$3" ]]; then
  3710. rm /etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json >/dev/null 2>&1
  3711. fi
  3712. # VLESS_TCP/reality
  3713. if echo "${selectCustomInstallType}" | grep -q ",7," || [[ "$1" == "all" ]]; then
  3714. echoContent skyBlue "\n===================== 配置VLESS+Reality =====================\n"
  3715. initXrayRealityPort
  3716. initRealityClientServersName
  3717. initRealityKey
  3718. initRealityMldsa65
  3719. cat <<EOF >/etc/v2ray-agent/xray/conf/07_VLESS_vision_reality_inbounds.json
  3720. {
  3721. "inbounds": [
  3722. {
  3723. "port": ${realityPort},
  3724. "protocol": "vless",
  3725. "tag": "VLESSReality",
  3726. "settings": {
  3727. "clients": $(initXrayClients 7),
  3728. "decryption": "none",
  3729. "fallbacks":[
  3730. {
  3731. "dest": "31305",
  3732. "xver": 1
  3733. }
  3734. ]
  3735. },
  3736. "streamSettings": {
  3737. "network": "tcp",
  3738. "security": "reality",
  3739. "realitySettings": {
  3740. "show": false,
  3741. "dest": "${realityServerName}:${realityDomainPort}",
  3742. "xver": 0,
  3743. "serverNames": [
  3744. "${realityServerName}"
  3745. ],
  3746. "privateKey": "${realityPrivateKey}",
  3747. "publicKey": "${realityPublicKey}",
  3748. "mldsa65Seed": "${realityMldsa65Seed}",
  3749. "mldsa65Verify": "${realityMldsa65Verify}",
  3750. "maxTimeDiff": 70000,
  3751. "shortIds": [
  3752. "",
  3753. "6ba85179e30d4fc2"
  3754. ]
  3755. }
  3756. }
  3757. }
  3758. ]
  3759. }
  3760. EOF
  3761. cat <<EOF >/etc/v2ray-agent/xray/conf/08_VLESS_vision_gRPC_inbounds.json
  3762. {
  3763. "inbounds": [
  3764. {
  3765. "port": 31305,
  3766. "listen": "127.0.0.1",
  3767. "protocol": "vless",
  3768. "tag": "VLESSRealityGRPC",
  3769. "settings": {
  3770. "clients": $(initXrayClients 8),
  3771. "decryption": "none"
  3772. },
  3773. "streamSettings": {
  3774. "network": "grpc",
  3775. "grpcSettings": {
  3776. "serviceName": "grpc",
  3777. "multiMode": true
  3778. },
  3779. "sockopt": {
  3780. "acceptProxyProtocol": true
  3781. }
  3782. }
  3783. }
  3784. ]
  3785. }
  3786. EOF
  3787. elif [[ -z "$3" ]]; then
  3788. rm /etc/v2ray-agent/xray/conf/07_VLESS_vision_reality_inbounds.json >/dev/null 2>&1
  3789. rm /etc/v2ray-agent/xray/conf/08_VLESS_vision_gRPC_inbounds.json >/dev/null 2>&1
  3790. fi
  3791. installSniffing
  3792. if [[ -z "$3" ]]; then
  3793. removeXrayOutbound wireguard_out_IPv4_route
  3794. removeXrayOutbound wireguard_out_IPv6_route
  3795. removeXrayOutbound wireguard_outbound
  3796. removeXrayOutbound IPv4_out
  3797. removeXrayOutbound IPv6_out
  3798. removeXrayOutbound socks5_outbound
  3799. removeXrayOutbound blackhole_out
  3800. removeXrayOutbound wireguard_out_IPv6
  3801. removeXrayOutbound wireguard_out_IPv4
  3802. addXrayOutbound z_direct_outbound
  3803. fi
  3804. }
  3805. # 初始化TCP Brutal
  3806. initTCPBrutal() {
  3807. echoContent skyBlue "\n进度 $2/${totalProgress} : 初始化TCP_Brutal配置"
  3808. read -r -p "是否使用TCP_Brutal?[y/n]:" tcpBrutalStatus
  3809. if [[ "${tcpBrutalStatus}" == "y" ]]; then
  3810. read -r -p "请输入本地带宽峰值的下行速度(默认:100,单位:Mbps):" tcpBrutalClientDownloadSpeed
  3811. if [[ -z "${tcpBrutalClientDownloadSpeed}" ]]; then
  3812. tcpBrutalClientDownloadSpeed=100
  3813. fi
  3814. read -r -p "请输入本地带宽峰值的上行速度(默认:50,单位:Mbps):" tcpBrutalClientUploadSpeed
  3815. if [[ -z "${tcpBrutalClientUploadSpeed}" ]]; then
  3816. tcpBrutalClientUploadSpeed=50
  3817. fi
  3818. fi
  3819. }
  3820. # 初始化sing-box配置文件
  3821. initSingBoxConfig() {
  3822. echoContent skyBlue "\n进度 $2/${totalProgress} : 初始化sing-box配置"
  3823. echo
  3824. local uuid=
  3825. local addClientsStatus=
  3826. local sslDomain=
  3827. if [[ -n "${domain}" ]]; then
  3828. sslDomain="${domain}"
  3829. elif [[ -n "${currentHost}" ]]; then
  3830. sslDomain="${currentHost}"
  3831. fi
  3832. if [[ -n "${currentUUID}" && -z "${lastInstallationConfig}" ]]; then
  3833. read -r -p "读取到上次用户配置,是否使用上次安装的配置 ?[y/n]:" historyUUIDStatus
  3834. if [[ "${historyUUIDStatus}" == "y" ]]; then
  3835. addClientsStatus=true
  3836. echoContent green "\n ---> 使用成功"
  3837. fi
  3838. elif [[ -n "${currentUUID}" && -n "${lastInstallationConfig}" ]]; then
  3839. addClientsStatus=true
  3840. fi
  3841. if [[ -z "${addClientsStatus}" ]]; then
  3842. echoContent yellow "请输入自定义UUID[需合法],[回车]随机UUID"
  3843. read -r -p 'UUID:' customUUID
  3844. if [[ -n ${customUUID} ]]; then
  3845. uuid=${customUUID}
  3846. else
  3847. uuid=$(/etc/v2ray-agent/sing-box/sing-box generate uuid)
  3848. fi
  3849. echoContent yellow "\n请输入自定义用户名[需合法],[回车]随机用户名"
  3850. read -r -p '用户名:' customEmail
  3851. if [[ -z ${customEmail} ]]; then
  3852. customEmail="$(echo "${uuid}" | cut -d "-" -f 1)-VLESS_TCP/TLS_Vision"
  3853. fi
  3854. fi
  3855. if [[ -z "${addClientsStatus}" && -z "${uuid}" ]]; then
  3856. addClientsStatus=
  3857. echoContent red "\n ---> uuid读取错误,随机生成"
  3858. uuid=$(/etc/v2ray-agent/sing-box/sing-box generate uuid)
  3859. fi
  3860. if [[ -n "${uuid}" ]]; then
  3861. currentClients='[{"uuid":"'${uuid}'","flow":"xtls-rprx-vision","name":"'${customEmail}'"}]'
  3862. echoContent yellow "\n ${customEmail}:${uuid}"
  3863. fi
  3864. # VLESS Vision
  3865. if echo "${selectCustomInstallType}" | grep -q ",0," || [[ "$1" == "all" ]]; then
  3866. echoContent yellow "\n===================== 配置VLESS+Vision =====================\n"
  3867. echoContent skyBlue "\n开始配置VLESS+Vision协议端口"
  3868. echo
  3869. mapfile -t result < <(initSingBoxPort "${singBoxVLESSVisionPort}")
  3870. echoContent green "\n ---> VLESS_Vision端口:${result[-1]}"
  3871. checkDNSIP "${domain}"
  3872. removeNginxDefaultConf
  3873. handleSingBox stop
  3874. checkPortOpen "${result[-1]}" "${domain}"
  3875. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/02_VLESS_TCP_inbounds.json
  3876. {
  3877. "inbounds":[
  3878. {
  3879. "type": "vless",
  3880. "listen":"::",
  3881. "listen_port":${result[-1]},
  3882. "tag":"VLESSTCP",
  3883. "users":$(initSingBoxClients 0),
  3884. "tls":{
  3885. "server_name": "${sslDomain}",
  3886. "enabled": true,
  3887. "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt",
  3888. "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key"
  3889. }
  3890. }
  3891. ]
  3892. }
  3893. EOF
  3894. elif [[ -z "$3" ]]; then
  3895. rm /etc/v2ray-agent/sing-box/conf/config/02_VLESS_TCP_inbounds.json >/dev/null 2>&1
  3896. fi
  3897. if echo "${selectCustomInstallType}" | grep -q ",1," || [[ "$1" == "all" ]]; then
  3898. echoContent yellow "\n===================== 配置VLESS+WS =====================\n"
  3899. echoContent skyBlue "\n开始配置VLESS+WS协议端口"
  3900. echo
  3901. mapfile -t result < <(initSingBoxPort "${singBoxVLESSWSPort}")
  3902. echoContent green "\n ---> VLESS_WS端口:${result[-1]}"
  3903. checkDNSIP "${domain}"
  3904. removeNginxDefaultConf
  3905. handleSingBox stop
  3906. randomPathFunction
  3907. checkPortOpen "${result[-1]}" "${domain}"
  3908. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/03_VLESS_WS_inbounds.json
  3909. {
  3910. "inbounds":[
  3911. {
  3912. "type": "vless",
  3913. "listen":"::",
  3914. "listen_port":${result[-1]},
  3915. "tag":"VLESSWS",
  3916. "users":$(initSingBoxClients 1),
  3917. "tls":{
  3918. "server_name": "${sslDomain}",
  3919. "enabled": true,
  3920. "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt",
  3921. "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key"
  3922. },
  3923. "transport": {
  3924. "type": "ws",
  3925. "path": "/${currentPath}ws",
  3926. "max_early_data": 2048,
  3927. "early_data_header_name": "Sec-WebSocket-Protocol"
  3928. }
  3929. }
  3930. ]
  3931. }
  3932. EOF
  3933. elif [[ -z "$3" ]]; then
  3934. rm /etc/v2ray-agent/sing-box/conf/config/03_VLESS_WS_inbounds.json >/dev/null 2>&1
  3935. fi
  3936. if echo "${selectCustomInstallType}" | grep -q ",3," || [[ "$1" == "all" ]]; then
  3937. echoContent yellow "\n===================== 配置VMess+ws =====================\n"
  3938. echoContent skyBlue "\n开始配置VMess+ws协议端口"
  3939. echo
  3940. mapfile -t result < <(initSingBoxPort "${singBoxVMessWSPort}")
  3941. echoContent green "\n ---> VMess_ws端口:${result[-1]}"
  3942. checkDNSIP "${domain}"
  3943. removeNginxDefaultConf
  3944. handleSingBox stop
  3945. randomPathFunction
  3946. checkPortOpen "${result[-1]}" "${domain}"
  3947. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/05_VMess_WS_inbounds.json
  3948. {
  3949. "inbounds":[
  3950. {
  3951. "type": "vmess",
  3952. "listen":"::",
  3953. "listen_port":${result[-1]},
  3954. "tag":"VMessWS",
  3955. "users":$(initSingBoxClients 3),
  3956. "tls":{
  3957. "server_name": "${sslDomain}",
  3958. "enabled": true,
  3959. "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt",
  3960. "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key"
  3961. },
  3962. "transport": {
  3963. "type": "ws",
  3964. "path": "/${currentPath}",
  3965. "max_early_data": 2048,
  3966. "early_data_header_name": "Sec-WebSocket-Protocol"
  3967. }
  3968. }
  3969. ]
  3970. }
  3971. EOF
  3972. elif [[ -z "$3" ]]; then
  3973. rm /etc/v2ray-agent/sing-box/conf/config/05_VMess_WS_inbounds.json >/dev/null 2>&1
  3974. fi
  3975. # VLESS_Reality_Vision
  3976. if echo "${selectCustomInstallType}" | grep -q ",7," || [[ "$1" == "all" ]]; then
  3977. echoContent yellow "\n================= 配置VLESS+Reality+Vision =================\n"
  3978. initRealityClientServersName
  3979. initRealityKey
  3980. echoContent skyBlue "\n开始配置VLESS+Reality+Vision协议端口"
  3981. echo
  3982. mapfile -t result < <(initSingBoxPort "${singBoxVLESSRealityVisionPort}")
  3983. echoContent green "\n ---> VLESS_Reality_Vision端口:${result[-1]}"
  3984. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/07_VLESS_vision_reality_inbounds.json
  3985. {
  3986. "inbounds": [
  3987. {
  3988. "type": "vless",
  3989. "listen":"::",
  3990. "listen_port":${result[-1]},
  3991. "tag": "VLESSReality",
  3992. "users":$(initSingBoxClients 7),
  3993. "tls": {
  3994. "enabled": true,
  3995. "server_name": "${realityServerName}",
  3996. "reality": {
  3997. "enabled": true,
  3998. "handshake":{
  3999. "server": "${realityServerName}",
  4000. "server_port":${realityDomainPort}
  4001. },
  4002. "private_key": "${realityPrivateKey}",
  4003. "short_id": [
  4004. "",
  4005. "6ba85179e30d4fc2"
  4006. ]
  4007. }
  4008. }
  4009. }
  4010. ]
  4011. }
  4012. EOF
  4013. elif [[ -z "$3" ]]; then
  4014. rm /etc/v2ray-agent/sing-box/conf/config/07_VLESS_vision_reality_inbounds.json >/dev/null 2>&1
  4015. fi
  4016. if echo "${selectCustomInstallType}" | grep -q ",8," || [[ "$1" == "all" ]]; then
  4017. echoContent yellow "\n================== 配置VLESS+Reality+gRPC ==================\n"
  4018. initRealityClientServersName
  4019. initRealityKey
  4020. echoContent skyBlue "\n开始配置VLESS+Reality+gRPC协议端口"
  4021. echo
  4022. mapfile -t result < <(initSingBoxPort "${singBoxVLESSRealityGRPCPort}")
  4023. echoContent green "\n ---> VLESS_Reality_gPRC端口:${result[-1]}"
  4024. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/08_VLESS_vision_gRPC_inbounds.json
  4025. {
  4026. "inbounds": [
  4027. {
  4028. "type": "vless",
  4029. "listen":"::",
  4030. "listen_port":${result[-1]},
  4031. "users":$(initSingBoxClients 8),
  4032. "tag": "VLESSRealityGRPC",
  4033. "tls": {
  4034. "enabled": true,
  4035. "server_name": "${realityServerName}",
  4036. "reality": {
  4037. "enabled": true,
  4038. "handshake":{
  4039. "server":"${realityServerName}",
  4040. "server_port":${realityDomainPort}
  4041. },
  4042. "private_key": "${realityPrivateKey}",
  4043. "short_id": [
  4044. "",
  4045. "6ba85179e30d4fc2"
  4046. ]
  4047. }
  4048. },
  4049. "transport": {
  4050. "type": "grpc",
  4051. "service_name": "grpc"
  4052. }
  4053. }
  4054. ]
  4055. }
  4056. EOF
  4057. elif [[ -z "$3" ]]; then
  4058. rm /etc/v2ray-agent/sing-box/conf/config/08_VLESS_vision_gRPC_inbounds.json >/dev/null 2>&1
  4059. fi
  4060. if echo "${selectCustomInstallType}" | grep -q ",6," || [[ "$1" == "all" ]]; then
  4061. echoContent yellow "\n================== 配置 Hysteria2 ==================\n"
  4062. echoContent skyBlue "\n开始配置Hysteria2协议端口"
  4063. echo
  4064. mapfile -t result < <(initSingBoxPort "${singBoxHysteria2Port}")
  4065. echoContent green "\n ---> Hysteria2端口:${result[-1]}"
  4066. initHysteria2Network
  4067. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/06_hysteria2_inbounds.json
  4068. {
  4069. "inbounds": [
  4070. {
  4071. "type": "hysteria2",
  4072. "listen": "::",
  4073. "listen_port": ${result[-1]},
  4074. "users": $(initSingBoxClients 6),
  4075. "up_mbps":${hysteria2ClientDownloadSpeed},
  4076. "down_mbps":${hysteria2ClientUploadSpeed},
  4077. "tls": {
  4078. "enabled": true,
  4079. "server_name":"${sslDomain}",
  4080. "alpn": [
  4081. "h3"
  4082. ],
  4083. "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt",
  4084. "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key"
  4085. }
  4086. }
  4087. ]
  4088. }
  4089. EOF
  4090. elif [[ -z "$3" ]]; then
  4091. rm /etc/v2ray-agent/sing-box/conf/config/06_hysteria2_inbounds.json >/dev/null 2>&1
  4092. fi
  4093. if echo "${selectCustomInstallType}" | grep -q ",4," || [[ "$1" == "all" ]]; then
  4094. echoContent yellow "\n================== 配置 Trojan ==================\n"
  4095. echoContent skyBlue "\n开始配置Trojan协议端口"
  4096. echo
  4097. mapfile -t result < <(initSingBoxPort "${singBoxTrojanPort}")
  4098. echoContent green "\n ---> Trojan端口:${result[-1]}"
  4099. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/04_trojan_TCP_inbounds.json
  4100. {
  4101. "inbounds": [
  4102. {
  4103. "type": "trojan",
  4104. "listen": "::",
  4105. "listen_port": ${result[-1]},
  4106. "users": $(initSingBoxClients 4),
  4107. "tls": {
  4108. "enabled": true,
  4109. "server_name":"${sslDomain}",
  4110. "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt",
  4111. "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key"
  4112. }
  4113. }
  4114. ]
  4115. }
  4116. EOF
  4117. elif [[ -z "$3" ]]; then
  4118. rm /etc/v2ray-agent/sing-box/conf/config/04_trojan_TCP_inbounds.json >/dev/null 2>&1
  4119. fi
  4120. if echo "${selectCustomInstallType}" | grep -q ",9," || [[ "$1" == "all" ]]; then
  4121. echoContent yellow "\n==================== 配置 Tuic =====================\n"
  4122. echoContent skyBlue "\n开始配置Tuic协议端口"
  4123. echo
  4124. mapfile -t result < <(initSingBoxPort "${singBoxTuicPort}")
  4125. echoContent green "\n ---> Tuic端口:${result[-1]}"
  4126. initTuicProtocol
  4127. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/09_tuic_inbounds.json
  4128. {
  4129. "inbounds": [
  4130. {
  4131. "type": "tuic",
  4132. "listen": "::",
  4133. "tag": "singbox-tuic-in",
  4134. "listen_port": ${result[-1]},
  4135. "users": $(initSingBoxClients 9),
  4136. "congestion_control": "${tuicAlgorithm}",
  4137. "tls": {
  4138. "enabled": true,
  4139. "server_name":"${sslDomain}",
  4140. "alpn": [
  4141. "h3"
  4142. ],
  4143. "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt",
  4144. "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key"
  4145. }
  4146. }
  4147. ]
  4148. }
  4149. EOF
  4150. elif [[ -z "$3" ]]; then
  4151. rm /etc/v2ray-agent/sing-box/conf/config/09_tuic_inbounds.json >/dev/null 2>&1
  4152. fi
  4153. if echo "${selectCustomInstallType}" | grep -q ",10," || [[ "$1" == "all" ]]; then
  4154. echoContent yellow "\n==================== 配置 Naive =====================\n"
  4155. echoContent skyBlue "\n开始配置Naive协议端口"
  4156. echo
  4157. mapfile -t result < <(initSingBoxPort "${singBoxNaivePort}")
  4158. echoContent green "\n ---> Naive端口:${result[-1]}"
  4159. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/10_naive_inbounds.json
  4160. {
  4161. "inbounds": [
  4162. {
  4163. "type": "naive",
  4164. "listen": "::",
  4165. "tag": "singbox-naive-in",
  4166. "listen_port": ${result[-1]},
  4167. "users": $(initSingBoxClients 10),
  4168. "tls": {
  4169. "enabled": true,
  4170. "server_name":"${sslDomain}",
  4171. "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt",
  4172. "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key"
  4173. }
  4174. }
  4175. ]
  4176. }
  4177. EOF
  4178. elif [[ -z "$3" ]]; then
  4179. rm /etc/v2ray-agent/sing-box/conf/config/10_naive_inbounds.json >/dev/null 2>&1
  4180. fi
  4181. if echo "${selectCustomInstallType}" | grep -q ",11," || [[ "$1" == "all" ]]; then
  4182. echoContent yellow "\n===================== 配置VMess+HTTPUpgrade =====================\n"
  4183. echoContent skyBlue "\n开始配置VMess+HTTPUpgrade协议端口"
  4184. echo
  4185. mapfile -t result < <(initSingBoxPort "${singBoxVMessHTTPUpgradePort}")
  4186. echoContent green "\n ---> VMess_HTTPUpgrade端口:${result[-1]}"
  4187. checkDNSIP "${domain}"
  4188. removeNginxDefaultConf
  4189. handleSingBox stop
  4190. randomPathFunction
  4191. rm -rf "${nginxConfigPath}sing_box_VMess_HTTPUpgrade.conf" >/dev/null 2>&1
  4192. checkPortOpen "${result[-1]}" "${domain}"
  4193. singBoxNginxConfig "$1" "${result[-1]}"
  4194. bootStartup nginx
  4195. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/11_VMess_HTTPUpgrade_inbounds.json
  4196. {
  4197. "inbounds":[
  4198. {
  4199. "type": "vmess",
  4200. "listen":"127.0.0.1",
  4201. "listen_port":31306,
  4202. "tag":"VMessHTTPUpgrade",
  4203. "users":$(initSingBoxClients 11),
  4204. "transport": {
  4205. "type": "httpupgrade",
  4206. "path": "/${currentPath}"
  4207. }
  4208. }
  4209. ]
  4210. }
  4211. EOF
  4212. elif [[ -z "$3" ]]; then
  4213. rm /etc/v2ray-agent/sing-box/conf/config/11_VMess_HTTPUpgrade_inbounds.json >/dev/null 2>&1
  4214. fi
  4215. if echo "${selectCustomInstallType}" | grep -q ",13," || [[ "$1" == "all" ]]; then
  4216. echoContent yellow "\n================== 配置 AnyTLS ==================\n"
  4217. echoContent skyBlue "\n开始配置AnyTLS协议端口"
  4218. echo
  4219. mapfile -t result < <(initSingBoxPort "${singBoxAnyTLSPort}")
  4220. echoContent green "\n ---> AnyTLS端口:${result[-1]}"
  4221. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/13_anytls_inbounds.json
  4222. {
  4223. "inbounds": [
  4224. {
  4225. "type": "anytls",
  4226. "listen": "::",
  4227. "tag":"anytls",
  4228. "listen_port": ${result[-1]},
  4229. "users": $(initSingBoxClients 13),
  4230. "tls": {
  4231. "enabled": true,
  4232. "server_name":"${sslDomain}",
  4233. "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt",
  4234. "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key"
  4235. }
  4236. }
  4237. ]
  4238. }
  4239. EOF
  4240. elif [[ -z "$3" ]]; then
  4241. rm /etc/v2ray-agent/sing-box/conf/config/13_anytls_inbounds.json >/dev/null 2>&1
  4242. fi
  4243. if [[ -z "$3" ]]; then
  4244. removeSingBoxConfig wireguard_endpoints_IPv4_route
  4245. removeSingBoxConfig wireguard_endpoints_IPv6_route
  4246. removeSingBoxConfig wireguard_endpoints_IPv4
  4247. removeSingBoxConfig wireguard_endpoints_IPv6
  4248. removeSingBoxConfig IPv4_out
  4249. removeSingBoxConfig IPv6_out
  4250. removeSingBoxConfig IPv6_route
  4251. removeSingBoxConfig block
  4252. removeSingBoxConfig cn_block_outbound
  4253. removeSingBoxConfig cn_block_route
  4254. removeSingBoxConfig 01_direct_outbound
  4255. removeSingBoxConfig block_domain_outbound
  4256. removeSingBoxConfig dns
  4257. fi
  4258. }
  4259. # 初始化 sing-box订阅配置
  4260. initSubscribeLocalConfig() {
  4261. rm -rf /etc/v2ray-agent/subscribe_local/sing-box/*
  4262. }
  4263. # 通用
  4264. defaultBase64Code() {
  4265. local type=$1
  4266. local port=$2
  4267. local email=$3
  4268. local id=$4
  4269. local add=$5
  4270. local path=$6
  4271. local user=
  4272. user=$(echo "${email}" | awk -F "[-]" '{print $1}')
  4273. if [[ ! -f "/etc/v2ray-agent/subscribe_local/sing-box/${user}" ]]; then
  4274. echo [] >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4275. fi
  4276. local singBoxSubscribeLocalConfig=
  4277. if [[ "${type}" == "vlesstcp" ]]; then
  4278. echoContent yellow " ---> 通用格式(VLESS+TCP+TLS_Vision)"
  4279. echoContent green " vless://${id}@${currentHost}:${port}?encryption=none&security=tls&fp=chrome&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-vision#${email}\n"
  4280. echoContent yellow " ---> 格式化明文(VLESS+TCP+TLS_Vision)"
  4281. echoContent green "协议类型:VLESS,地址:${currentHost},端口:${port},用户ID:${id},安全:tls,client-fingerprint: chrome,传输方式:tcp,flow:xtls-rprx-vision,账户名:${email}\n"
  4282. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4283. vless://${id}@${currentHost}:${port}?encryption=none&security=tls&type=tcp&host=${currentHost}&fp=chrome&headerType=none&sni=${currentHost}&flow=xtls-rprx-vision#${email}
  4284. EOF
  4285. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4286. - name: "${email}"
  4287. type: vless
  4288. server: ${currentHost}
  4289. port: ${port}
  4290. uuid: ${id}
  4291. network: tcp
  4292. tls: true
  4293. udp: true
  4294. flow: xtls-rprx-vision
  4295. client-fingerprint: chrome
  4296. EOF
  4297. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vless\",\"server\":\"${currentHost}\",\"server_port\":${port},\"uuid\":\"${id}\",\"flow\":\"xtls-rprx-vision\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"packet_encoding\":\"xudp\"}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4298. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4299. echoContent yellow " ---> 二维码 VLESS(VLESS+TCP+TLS_Vision)"
  4300. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${currentHost}%3A${port}%3Fencryption%3Dnone%26fp%3Dchrome%26security%3Dtls%26type%3Dtcp%26${currentHost}%3D${currentHost}%26headerType%3Dnone%26sni%3D${currentHost}%26flow%3Dxtls-rprx-vision%23${email}\n"
  4301. elif [[ "${type}" == "vmessws" ]]; then
  4302. qrCodeBase64Default=$(echo -n "{\"port\":${port},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"${path}\",\"net\":\"ws\",\"add\":\"${add}\",\"allowInsecure\":0,\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}" | base64 -w 0)
  4303. qrCodeBase64Default="${qrCodeBase64Default// /}"
  4304. echoContent yellow " ---> 通用json(VMess+WS+TLS)"
  4305. echoContent green " {\"port\":${port},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"${path}\",\"net\":\"ws\",\"add\":\"${add}\",\"allowInsecure\":0,\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}\n"
  4306. echoContent yellow " ---> 通用vmess(VMess+WS+TLS)链接"
  4307. echoContent green " vmess://${qrCodeBase64Default}\n"
  4308. echoContent yellow " ---> 二维码 vmess(VMess+WS+TLS)"
  4309. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4310. vmess://${qrCodeBase64Default}
  4311. EOF
  4312. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4313. - name: "${email}"
  4314. type: vmess
  4315. server: ${add}
  4316. port: ${port}
  4317. uuid: ${id}
  4318. alterId: 0
  4319. cipher: none
  4320. udp: true
  4321. tls: true
  4322. client-fingerprint: chrome
  4323. servername: ${currentHost}
  4324. network: ws
  4325. ws-opts:
  4326. path: ${path}
  4327. headers:
  4328. Host: ${currentHost}
  4329. EOF
  4330. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vmess\",\"server\":\"${add}\",\"server_port\":${port},\"uuid\":\"${id}\",\"alter_id\":0,\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"packet_encoding\":\"packetaddr\",\"transport\":{\"type\":\"ws\",\"path\":\"${path}\",\"max_early_data\":2048,\"early_data_header_name\":\"Sec-WebSocket-Protocol\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4331. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4332. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess://${qrCodeBase64Default}\n"
  4333. elif [[ "${type}" == "vlessws" ]]; then
  4334. echoContent yellow " ---> 通用格式(VLESS+WS+TLS)"
  4335. echoContent green " vless://${id}@${add}:${port}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&fp=chrome&path=${path}#${email}\n"
  4336. echoContent yellow " ---> 格式化明文(VLESS+WS+TLS)"
  4337. echoContent green " 协议类型:VLESS,地址:${add},伪装域名/SNI:${currentHost},端口:${port},client-fingerprint: chrome,用户ID:${id},安全:tls,传输方式:ws,路径:${path},账户名:${email}\n"
  4338. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4339. vless://${id}@${add}:${port}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&fp=chrome&path=${path}#${email}
  4340. EOF
  4341. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4342. - name: "${email}"
  4343. type: vless
  4344. server: ${add}
  4345. port: ${port}
  4346. uuid: ${id}
  4347. udp: true
  4348. tls: true
  4349. network: ws
  4350. client-fingerprint: chrome
  4351. servername: ${currentHost}
  4352. ws-opts:
  4353. path: ${path}
  4354. headers:
  4355. Host: ${currentHost}
  4356. EOF
  4357. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vless\",\"server\":\"${add}\",\"server_port\":${port},\"uuid\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"multiplex\":{\"enabled\":false,\"protocol\":\"smux\",\"max_streams\":32},\"packet_encoding\":\"xudp\",\"transport\":{\"type\":\"ws\",\"path\":\"${path}\",\"headers\":{\"Host\":\"${currentHost}\"}}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4358. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4359. echoContent yellow " ---> 二维码 VLESS(VLESS+WS+TLS)"
  4360. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${add}%3A${port}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dws%26host%3D${currentHost}%26fp%3Dchrome%26sni%3D${currentHost}%26path%3D${path}%23${email}"
  4361. elif [[ "${type}" == "vlessXHTTP" ]]; then
  4362. echoContent yellow " ---> 通用格式(VLESS+reality+XHTTP)"
  4363. echoContent green " vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&type=xhttp&sni=${xrayVLESSRealityXHTTPServerName}&host=${xrayVLESSRealityXHTTPServerName}&fp=chrome&path=${path}&pbk=${currentRealityXHTTPPublicKey}&sid=6ba85179e30d4fc2#${email}\n"
  4364. echoContent yellow " ---> 格式化明文(VLESS+reality+XHTTP)"
  4365. echoContent green "协议类型:VLESS reality,地址:$(getPublicIP),publicKey:${currentRealityXHTTPPublicKey},shortId: 6ba85179e30d4fc2,serverNames:${xrayVLESSRealityXHTTPServerName},端口:${port},路径:${path},SNI:${xrayVLESSRealityXHTTPServerName},伪装域名:${xrayVLESSRealityXHTTPServerName},用户ID:${id},传输方式:xhttp,账户名:${email}\n"
  4366. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4367. vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&type=xhttp&sni=${xrayVLESSRealityXHTTPServerName}&fp=chrome&path=${path}&pbk=${currentRealityXHTTPPublicKey}&sid=6ba85179e30d4fc2#${email}
  4368. EOF
  4369. echoContent yellow " ---> 二维码 VLESS(VLESS+reality+XHTTP)"
  4370. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40$(getPublicIP)%3A${port}%3Fencryption%3Dnone%26security%3Dreality%26type%3Dtcp%26sni%3D${xrayVLESSRealityXHTTPServerName}%26fp%3Dchrome%26path%3D${path}%26host%3D${xrayVLESSRealityXHTTPServerName}%26pbk%3D${currentRealityXHTTPPublicKey}%26sid%3D6ba85179e30d4fc2%23${email}\n"
  4371. elif
  4372. [[ "${type}" == "vlessgrpc" ]]
  4373. then
  4374. echoContent yellow " ---> 通用格式(VLESS+gRPC+TLS)"
  4375. echoContent green " vless://${id}@${add}:${port}?encryption=none&security=tls&type=grpc&host=${currentHost}&path=${currentPath}grpc&fp=chrome&serviceName=${currentPath}grpc&alpn=h2&sni=${currentHost}#${email}\n"
  4376. echoContent yellow " ---> 格式化明文(VLESS+gRPC+TLS)"
  4377. echoContent green " 协议类型:VLESS,地址:${add},伪装域名/SNI:${currentHost},端口:${port},用户ID:${id},安全:tls,传输方式:gRPC,alpn:h2,client-fingerprint: chrome,serviceName:${currentPath}grpc,账户名:${email}\n"
  4378. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4379. vless://${id}@${add}:${port}?encryption=none&security=tls&type=grpc&host=${currentHost}&path=${currentPath}grpc&serviceName=${currentPath}grpc&fp=chrome&alpn=h2&sni=${currentHost}#${email}
  4380. EOF
  4381. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4382. - name: "${email}"
  4383. type: vless
  4384. server: ${add}
  4385. port: ${port}
  4386. uuid: ${id}
  4387. udp: true
  4388. tls: true
  4389. network: grpc
  4390. client-fingerprint: chrome
  4391. servername: ${currentHost}
  4392. grpc-opts:
  4393. grpc-service-name: ${currentPath}grpc
  4394. EOF
  4395. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\": \"vless\",\"server\": \"${add}\",\"server_port\": ${port},\"uuid\": \"${id}\",\"tls\": { \"enabled\": true, \"server_name\": \"${currentHost}\", \"utls\": { \"enabled\": true, \"fingerprint\": \"chrome\" }},\"packet_encoding\": \"xudp\",\"transport\": { \"type\": \"grpc\", \"service_name\": \"${currentPath}grpc\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4396. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4397. echoContent yellow " ---> 二维码 VLESS(VLESS+gRPC+TLS)"
  4398. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${add}%3A${port}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dgrpc%26host%3D${currentHost}%26serviceName%3D${currentPath}grpc%26fp%3Dchrome%26path%3D${currentPath}grpc%26sni%3D${currentHost}%26alpn%3Dh2%23${email}"
  4399. elif [[ "${type}" == "trojan" ]]; then
  4400. # URLEncode
  4401. echoContent yellow " ---> Trojan(TLS)"
  4402. echoContent green " trojan://${id}@${currentHost}:${port}?peer=${currentHost}&fp=chrome&sni=${currentHost}&alpn=http/1.1#${currentHost}_Trojan\n"
  4403. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4404. trojan://${id}@${currentHost}:${port}?peer=${currentHost}&fp=chrome&sni=${currentHost}&alpn=http/1.1#${email}_Trojan
  4405. EOF
  4406. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4407. - name: "${email}"
  4408. type: trojan
  4409. server: ${currentHost}
  4410. port: ${port}
  4411. password: ${id}
  4412. client-fingerprint: chrome
  4413. udp: true
  4414. sni: ${currentHost}
  4415. EOF
  4416. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"trojan\",\"server\":\"${currentHost}\",\"server_port\":${port},\"password\":\"${id}\",\"tls\":{\"alpn\":[\"http/1.1\"],\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4417. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4418. echoContent yellow " ---> 二维码 Trojan(TLS)"
  4419. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3a%2f%2f${id}%40${currentHost}%3a${port}%3fpeer%3d${currentHost}%26fp%3Dchrome%26sni%3d${currentHost}%26alpn%3Dhttp/1.1%23${email}\n"
  4420. elif [[ "${type}" == "trojangrpc" ]]; then
  4421. # URLEncode
  4422. echoContent yellow " ---> Trojan gRPC(TLS)"
  4423. echoContent green " trojan://${id}@${add}:${port}?encryption=none&peer=${currentHost}&fp=chrome&security=tls&type=grpc&sni=${currentHost}&alpn=h2&path=${currentPath}trojangrpc&serviceName=${currentPath}trojangrpc#${email}\n"
  4424. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4425. trojan://${id}@${add}:${port}?encryption=none&peer=${currentHost}&security=tls&type=grpc&fp=chrome&sni=${currentHost}&alpn=h2&path=${currentPath}trojangrpc&serviceName=${currentPath}trojangrpc#${email}
  4426. EOF
  4427. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4428. - name: "${email}"
  4429. server: ${add}
  4430. port: ${port}
  4431. type: trojan
  4432. password: ${id}
  4433. network: grpc
  4434. sni: ${currentHost}
  4435. udp: true
  4436. grpc-opts:
  4437. grpc-service-name: ${currentPath}trojangrpc
  4438. EOF
  4439. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"trojan\",\"server\":\"${add}\",\"server_port\":${port},\"password\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"insecure\":true,\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"transport\":{\"type\":\"grpc\",\"service_name\":\"${currentPath}trojangrpc\",\"idle_timeout\":\"15s\",\"ping_timeout\":\"15s\",\"permit_without_stream\":false},\"multiplex\":{\"enabled\":false,\"protocol\":\"smux\",\"max_streams\":32}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4440. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4441. echoContent yellow " ---> 二维码 Trojan gRPC(TLS)"
  4442. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3a%2f%2f${id}%40${add}%3a${port}%3Fencryption%3Dnone%26fp%3Dchrome%26security%3Dtls%26peer%3d${currentHost}%26type%3Dgrpc%26sni%3d${currentHost}%26path%3D${currentPath}trojangrpc%26alpn%3Dh2%26serviceName%3D${currentPath}trojangrpc%23${email}\n"
  4443. elif [[ "${type}" == "hysteria" ]]; then
  4444. echoContent yellow " ---> Hysteria(TLS)"
  4445. local clashMetaPortContent="port: ${port}"
  4446. local multiPort=
  4447. local multiPortEncode
  4448. if echo "${port}" | grep -q "-"; then
  4449. clashMetaPortContent="ports: ${port}"
  4450. multiPort="mport=${port}&"
  4451. multiPortEncode="mport%3D${port}%26"
  4452. fi
  4453. echoContent green " hysteria2://${id}@${currentHost}:${singBoxHysteria2Port}?${multiPort}peer=${currentHost}&insecure=0&sni=${currentHost}&alpn=h3#${email}\n"
  4454. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4455. hysteria2://${id}@${currentHost}:${singBoxHysteria2Port}?${multiPort}peer=${currentHost}&insecure=0&sni=${currentHost}&alpn=h3#${email}
  4456. EOF
  4457. echoContent yellow " ---> v2rayN(hysteria+TLS)"
  4458. echo "{\"server\": \"${currentHost}:${port}\",\"socks5\": { \"listen\": \"127.0.0.1:7798\", \"timeout\": 300},\"auth\":\"${id}\",\"tls\":{\"sni\":\"${currentHost}\"}}" | jq
  4459. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4460. - name: "${email}"
  4461. type: hysteria2
  4462. server: ${currentHost}
  4463. ${clashMetaPortContent}
  4464. password: ${id}
  4465. alpn:
  4466. - h3
  4467. sni: ${currentHost}
  4468. up: "${hysteria2ClientUploadSpeed} Mbps"
  4469. down: "${hysteria2ClientDownloadSpeed} Mbps"
  4470. EOF
  4471. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"hysteria2\",\"server\":\"${currentHost}\",\"server_port\":${singBoxHysteria2Port},\"up_mbps\":${hysteria2ClientUploadSpeed},\"down_mbps\":${hysteria2ClientDownloadSpeed},\"password\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"alpn\":[\"h3\"]}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4472. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4473. echoContent yellow " ---> 二维码 Hysteria2(TLS)"
  4474. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=hysteria2%3A%2F%2F${id}%40${currentHost}%3A${singBoxHysteria2Port}%3F${multiPortEncode}peer%3D${currentHost}%26insecure%3D0%26sni%3D${currentHost}%26alpn%3Dh3%23${email}\n"
  4475. elif [[ "${type}" == "vlessReality" ]]; then
  4476. local realityServerName=${xrayVLESSRealityServerName}
  4477. local publicKey=${currentRealityPublicKey}
  4478. local realityMldsa65Verify=${currentRealityMldsa65Verify}
  4479. if [[ "${coreInstallType}" == "2" ]]; then
  4480. realityServerName=${singBoxVLESSRealityVisionServerName}
  4481. publicKey=${singBoxVLESSRealityPublicKey}
  4482. fi
  4483. echoContent yellow " ---> 通用格式(VLESS+reality+uTLS+Vision)"
  4484. echoContent green " vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&pqv=${realityMldsa65Verify}&type=tcp&sni=${realityServerName}&fp=chrome&pbk=${publicKey}&sid=6ba85179e30d4fc2&flow=xtls-rprx-vision#${email}\n"
  4485. echoContent yellow " ---> 格式化明文(VLESS+reality+uTLS+Vision)"
  4486. echoContent green "协议类型:VLESS reality,地址:$(getPublicIP),publicKey:${publicKey},shortId: 6ba85179e30d4fc2,pqv=${realityMldsa65Verify},serverNames:${realityServerName},端口:${port},用户ID:${id},传输方式:tcp,账户名:${email}\n"
  4487. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4488. vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&pqv=${realityMldsa65Verify}&type=tcp&sni=${realityServerName}&fp=chrome&pbk=${publicKey}&sid=6ba85179e30d4fc2&flow=xtls-rprx-vision#${email}
  4489. EOF
  4490. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4491. - name: "${email}"
  4492. type: vless
  4493. server: $(getPublicIP)
  4494. port: ${port}
  4495. uuid: ${id}
  4496. network: tcp
  4497. tls: true
  4498. udp: true
  4499. flow: xtls-rprx-vision
  4500. servername: ${realityServerName}
  4501. reality-opts:
  4502. public-key: ${publicKey}
  4503. short-id: 6ba85179e30d4fc2
  4504. client-fingerprint: chrome
  4505. EOF
  4506. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vless\",\"server\":\"$(getPublicIP)\",\"server_port\":${port},\"uuid\":\"${id}\",\"flow\":\"xtls-rprx-vision\",\"tls\":{\"enabled\":true,\"server_name\":\"${realityServerName}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"},\"reality\":{\"enabled\":true,\"public_key\":\"${publicKey}\",\"short_id\":\"6ba85179e30d4fc2\"}},\"packet_encoding\":\"xudp\"}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4507. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4508. echoContent yellow " ---> 二维码 VLESS(VLESS+reality+uTLS+Vision)"
  4509. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40$(getPublicIP)%3A${port}%3Fencryption%3Dnone%26security%3Dreality%26type%3Dtcp%26sni%3D${realityServerName}%26fp%3Dchrome%26pbk%3D${publicKey}%26sid%3D6ba85179e30d4fc2%26flow%3Dxtls-rprx-vision%23${email}\n"
  4510. elif [[ "${type}" == "vlessRealityGRPC" ]]; then
  4511. local realityServerName=${xrayVLESSRealityServerName}
  4512. local publicKey=${currentRealityPublicKey}
  4513. local realityMldsa65Verify=${currentRealityMldsa65Verify}
  4514. if [[ "${coreInstallType}" == "2" ]]; then
  4515. realityServerName=${singBoxVLESSRealityGRPCServerName}
  4516. publicKey=${singBoxVLESSRealityPublicKey}
  4517. fi
  4518. echoContent yellow " ---> 通用格式(VLESS+reality+uTLS+gRPC)"
  4519. # pqv=${realityMldsa65Verify}&
  4520. echoContent green " vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&type=grpc&sni=${realityServerName}&fp=chrome&pbk=${publicKey}&sid=6ba85179e30d4fc2&path=grpc&serviceName=grpc#${email}\n"
  4521. echoContent yellow " ---> 格式化明文(VLESS+reality+uTLS+gRPC)"
  4522. # pqv=${realityMldsa65Verify},
  4523. echoContent green "协议类型:VLESS reality,serviceName:grpc,地址:$(getPublicIP),publicKey:${publicKey},shortId: 6ba85179e30d4fc2,serverNames:${realityServerName},端口:${port},用户ID:${id},传输方式:gRPC,client-fingerprint:chrome,账户名:${email}\n"
  4524. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4525. vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&pqv=${realityMldsa65Verify}&type=grpc&sni=${realityServerName}&fp=chrome&pbk=${publicKey}&sid=6ba85179e30d4fc2&path=grpc&serviceName=grpc#${email}
  4526. EOF
  4527. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4528. - name: "${email}"
  4529. type: vless
  4530. server: $(getPublicIP)
  4531. port: ${port}
  4532. uuid: ${id}
  4533. network: grpc
  4534. tls: true
  4535. udp: true
  4536. servername: ${realityServerName}
  4537. reality-opts:
  4538. public-key: ${publicKey}
  4539. short-id: 6ba85179e30d4fc2
  4540. grpc-opts:
  4541. grpc-service-name: "grpc"
  4542. client-fingerprint: chrome
  4543. EOF
  4544. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vless\",\"server\":\"$(getPublicIP)\",\"server_port\":${port},\"uuid\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${realityServerName}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"},\"reality\":{\"enabled\":true,\"public_key\":\"${publicKey}\",\"short_id\":\"6ba85179e30d4fc2\"}},\"packet_encoding\":\"xudp\",\"transport\":{\"type\":\"grpc\",\"service_name\":\"grpc\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4545. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4546. echoContent yellow " ---> 二维码 VLESS(VLESS+reality+uTLS+gRPC)"
  4547. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40$(getPublicIP)%3A${port}%3Fencryption%3Dnone%26security%3Dreality%26type%3Dgrpc%26sni%3D${realityServerName}%26fp%3Dchrome%26pbk%3D${publicKey}%26sid%3D6ba85179e30d4fc2%26path%3Dgrpc%26serviceName%3Dgrpc%23${email}\n"
  4548. elif [[ "${type}" == "tuic" ]]; then
  4549. local tuicUUID=
  4550. tuicUUID=$(echo "${id}" | awk -F "[_]" '{print $1}')
  4551. local tuicPassword=
  4552. tuicPassword=$(echo "${id}" | awk -F "[_]" '{print $2}')
  4553. if [[ -z "${email}" ]]; then
  4554. echoContent red " ---> 读取配置失败,请重新安装"
  4555. exit 0
  4556. fi
  4557. echoContent yellow " ---> 格式化明文(Tuic+TLS)"
  4558. echoContent green " 协议类型:Tuic,地址:${currentHost},端口:${port},uuid:${tuicUUID},password:${tuicPassword},congestion-controller:${tuicAlgorithm},alpn: h3,账户名:${email}\n"
  4559. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4560. tuic://${tuicUUID}:${tuicPassword}@${currentHost}:${port}?congestion_control=${tuicAlgorithm}&alpn=h3&sni=${currentHost}&udp_relay_mode=quic&allow_insecure=0#${email}
  4561. EOF
  4562. echoContent yellow " ---> v2rayN(Tuic+TLS)"
  4563. echo "{\"relay\": {\"server\": \"${currentHost}:${port}\",\"uuid\": \"${tuicUUID}\",\"password\": \"${tuicPassword}\",\"ip\": \"${currentHost}\",\"congestion_control\": \"${tuicAlgorithm}\",\"alpn\": [\"h3\"]},\"local\": {\"server\": \"127.0.0.1:7798\"},\"log_level\": \"warn\"}" | jq
  4564. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4565. - name: "${email}"
  4566. server: ${currentHost}
  4567. type: tuic
  4568. port: ${port}
  4569. uuid: ${tuicUUID}
  4570. password: ${tuicPassword}
  4571. alpn:
  4572. - h3
  4573. congestion-controller: ${tuicAlgorithm}
  4574. disable-sni: true
  4575. reduce-rtt: true
  4576. sni: ${email}
  4577. EOF
  4578. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\": \"tuic\",\"server\": \"${currentHost}\",\"server_port\": ${port},\"uuid\": \"${tuicUUID}\",\"password\": \"${tuicPassword}\",\"congestion_control\": \"${tuicAlgorithm}\",\"tls\": {\"enabled\": true,\"server_name\": \"${currentHost}\",\"alpn\": [\"h3\"]}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4579. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4580. echoContent yellow "\n ---> 二维码 Tuic"
  4581. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=tuic%3A%2F%2F${tuicUUID}%3A${tuicPassword}%40${currentHost}%3A${tuicPort}%3Fcongestion_control%3D${tuicAlgorithm}%26alpn%3Dh3%26sni%3D${currentHost}%26udp_relay_mode%3Dquic%26allow_insecure%3D0%23${email}\n"
  4582. elif [[ "${type}" == "naive" ]]; then
  4583. echoContent yellow " ---> Naive(TLS)"
  4584. echoContent green " naive+https://${email}:${id}@${currentHost}:${port}?padding=true#${email}\n"
  4585. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4586. naive+https://${email}:${id}@${currentHost}:${port}?padding=true#${email}
  4587. EOF
  4588. echoContent yellow " ---> 二维码 Naive(TLS)"
  4589. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=naive%2Bhttps%3A%2F%2F${email}%3A${id}%40${currentHost}%3A${port}%3Fpadding%3Dtrue%23${email}\n"
  4590. elif [[ "${type}" == "vmessHTTPUpgrade" ]]; then
  4591. qrCodeBase64Default=$(echo -n "{\"port\":${port},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"${path}\",\"net\":\"httpupgrade\",\"add\":\"${add}\",\"allowInsecure\":0,\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}" | base64 -w 0)
  4592. qrCodeBase64Default="${qrCodeBase64Default// /}"
  4593. echoContent yellow " ---> 通用json(VMess+HTTPUpgrade+TLS)"
  4594. echoContent green " {\"port\":${port},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"${path}\",\"net\":\"httpupgrade\",\"add\":\"${add}\",\"allowInsecure\":0,\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}\n"
  4595. echoContent yellow " ---> 通用vmess(VMess+HTTPUpgrade+TLS)链接"
  4596. echoContent green " vmess://${qrCodeBase64Default}\n"
  4597. echoContent yellow " ---> 二维码 vmess(VMess+HTTPUpgrade+TLS)"
  4598. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4599. vmess://${qrCodeBase64Default}
  4600. EOF
  4601. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4602. - name: "${email}"
  4603. type: vmess
  4604. server: ${add}
  4605. port: ${port}
  4606. uuid: ${id}
  4607. alterId: 0
  4608. cipher: auto
  4609. udp: true
  4610. tls: true
  4611. client-fingerprint: chrome
  4612. servername: ${currentHost}
  4613. network: ws
  4614. ws-opts:
  4615. path: ${path}
  4616. headers:
  4617. Host: ${currentHost}
  4618. v2ray-http-upgrade: true
  4619. EOF
  4620. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vmess\",\"server\":\"${add}\",\"server_port\":${port},\"uuid\":\"${id}\",\"security\":\"auto\",\"alter_id\":0,\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"packet_encoding\":\"packetaddr\",\"transport\":{\"type\":\"httpupgrade\",\"path\":\"${path}\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4621. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4622. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess://${qrCodeBase64Default}\n"
  4623. elif [[ "${type}" == "anytls" ]]; then
  4624. echoContent yellow " ---> AnyTLS"
  4625. echoContent yellow " ---> 格式化明文(AnyTLS)"
  4626. echoContent green "协议类型:anytls,地址:${currentHost},端口:${singBoxAnyTLSPort},用户ID:${id},传输方式:tcp,账户名:${email}\n"
  4627. echoContent green " anytls://${id}@${currentHost}:${singBoxAnyTLSPort}?peer=${currentHost}&insecure=0&sni=${currentHost}#${email}\n"
  4628. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/default/${user}"
  4629. anytls://${id}@${currentHost}:${singBoxAnyTLSPort}?peer=${currentHost}&insecure=0&sni=${currentHost}#${email}
  4630. EOF
  4631. cat <<EOF >>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}"
  4632. - name: "${email}"
  4633. type: anytls
  4634. port: ${singBoxAnyTLSPort}
  4635. server: ${currentHost}
  4636. password: ${id}
  4637. client-fingerprint: chrome
  4638. udp: true
  4639. sni: ${currentHost}
  4640. alpn:
  4641. - h2
  4642. - http/1.1
  4643. EOF
  4644. singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"anytls\",\"server\":\"${currentHost}\",\"server_port\":${singBoxAnyTLSPort},\"password\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}")
  4645. echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}"
  4646. echoContent yellow " ---> 二维码 AnyTLS"
  4647. echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=anytls%3A%2F%2F${id}%40${currentHost}%3A${singBoxAnyTLSPort}%3Fpeer%3D${currentHost}%26insecure%3D0%26sni%3D${currentHost}%23${email}\n"
  4648. fi
  4649. }
  4650. # 账号
  4651. showAccounts() {
  4652. readInstallType
  4653. readInstallProtocolType
  4654. readConfigHostPathUUID
  4655. readSingBoxConfig
  4656. echo
  4657. echoContent skyBlue "\n进度 $1/${totalProgress} : 账号"
  4658. initSubscribeLocalConfig
  4659. # VLESS TCP
  4660. if echo ${currentInstallProtocolType} | grep -q ",0,"; then
  4661. echoContent skyBlue "============================= VLESS TCP TLS_Vision [推荐] ==============================\n"
  4662. jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}02_VLESS_TCP_inbounds.json | jq -c '.[]' | while read -r user; do
  4663. local email=
  4664. email=$(echo "${user}" | jq -r .email//.name)
  4665. echoContent skyBlue "\n ---> 账号:${email}"
  4666. echo
  4667. defaultBase64Code vlesstcp "${currentDefaultPort}${singBoxVLESSVisionPort}" "${email}" "$(echo "${user}" | jq -r .id//.uuid)"
  4668. done
  4669. fi
  4670. # VLESS WS
  4671. if echo ${currentInstallProtocolType} | grep -q ",1,"; then
  4672. echoContent skyBlue "\n================================ VLESS WS TLS [仅CDN推荐] ================================\n"
  4673. jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}03_VLESS_WS_inbounds.json | jq -c '.[]' | while read -r user; do
  4674. local email=
  4675. email=$(echo "${user}" | jq -r .email//.name)
  4676. local vlessWSPort=${currentDefaultPort}
  4677. if [[ "${coreInstallType}" == "2" ]]; then
  4678. vlessWSPort="${singBoxVLESSWSPort}"
  4679. fi
  4680. echo
  4681. local path="${currentPath}ws"
  4682. if [[ ${coreInstallType} == "1" ]]; then
  4683. path="/${currentPath}ws"
  4684. elif [[ "${coreInstallType}" == "2" ]]; then
  4685. path="${singBoxVLESSWSPath}"
  4686. fi
  4687. local count=
  4688. while read -r line; do
  4689. echoContent skyBlue "\n ---> 账号:${email}${count}"
  4690. if [[ -n "${line}" ]]; then
  4691. defaultBase64Code vlessws "${vlessWSPort}" "${email}${count}" "$(echo "${user}" | jq -r .id//.uuid)" "${line}" "${path}"
  4692. count=$((count + 1))
  4693. echo
  4694. fi
  4695. done < <(echo "${currentCDNAddress}" | tr ',' '\n')
  4696. done
  4697. fi
  4698. # trojan grpc
  4699. if echo ${currentInstallProtocolType} | grep -q ",2,"; then
  4700. echoContent skyBlue "\n================================ Trojan gRPC TLS [仅CDN推荐] ================================\n"
  4701. jq .inbounds[0].settings.clients ${configPath}04_trojan_gRPC_inbounds.json | jq -c '.[]' | while read -r user; do
  4702. local email=
  4703. email=$(echo "${user}" | jq -r .email)
  4704. local count=
  4705. while read -r line; do
  4706. echoContent skyBlue "\n ---> 账号:${email}${count}"
  4707. echo
  4708. if [[ -n "${line}" ]]; then
  4709. defaultBase64Code trojangrpc "${currentDefaultPort}" "${email}${count}" "$(echo "${user}" | jq -r .password)" "${line}"
  4710. count=$((count + 1))
  4711. fi
  4712. done < <(echo "${currentCDNAddress}" | tr ',' '\n')
  4713. done
  4714. fi
  4715. # VMess WS
  4716. if echo ${currentInstallProtocolType} | grep -q ",3,"; then
  4717. echoContent skyBlue "\n================================ VMess WS TLS [仅CDN推荐] ================================\n"
  4718. local path="${currentPath}vws"
  4719. if [[ ${coreInstallType} == "1" ]]; then
  4720. path="/${currentPath}vws"
  4721. elif [[ "${coreInstallType}" == "2" ]]; then
  4722. path="${singBoxVMessWSPath}"
  4723. fi
  4724. jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}05_VMess_WS_inbounds.json | jq -c '.[]' | while read -r user; do
  4725. local email=
  4726. email=$(echo "${user}" | jq -r .email//.name)
  4727. local vmessPort=${currentDefaultPort}
  4728. if [[ "${coreInstallType}" == "2" ]]; then
  4729. vmessPort="${singBoxVMessWSPort}"
  4730. fi
  4731. local count=
  4732. while read -r line; do
  4733. echoContent skyBlue "\n ---> 账号:${email}${count}"
  4734. echo
  4735. if [[ -n "${line}" ]]; then
  4736. defaultBase64Code vmessws "${vmessPort}" "${email}${count}" "$(echo "${user}" | jq -r .id//.uuid)" "${line}" "${path}"
  4737. count=$((count + 1))
  4738. fi
  4739. done < <(echo "${currentCDNAddress}" | tr ',' '\n')
  4740. done
  4741. fi
  4742. # trojan tcp
  4743. if echo ${currentInstallProtocolType} | grep -q ",4,"; then
  4744. echoContent skyBlue "\n================================== Trojan TLS [不推荐] ==================================\n"
  4745. jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}04_trojan_TCP_inbounds.json | jq -c '.[]' | while read -r user; do
  4746. local email=
  4747. email=$(echo "${user}" | jq -r .email//.name)
  4748. echoContent skyBlue "\n ---> 账号:${email}"
  4749. defaultBase64Code trojan "${currentDefaultPort}${singBoxTrojanPort}" "${email}" "$(echo "${user}" | jq -r .password)"
  4750. done
  4751. fi
  4752. # VLESS grpc
  4753. if echo ${currentInstallProtocolType} | grep -q ",5,"; then
  4754. echoContent skyBlue "\n=============================== VLESS gRPC TLS [仅CDN推荐] ===============================\n"
  4755. jq .inbounds[0].settings.clients ${configPath}06_VLESS_gRPC_inbounds.json | jq -c '.[]' | while read -r user; do
  4756. local email=
  4757. email=$(echo "${user}" | jq -r .email)
  4758. local count=
  4759. while read -r line; do
  4760. echoContent skyBlue "\n ---> 账号:${email}${count}"
  4761. echo
  4762. if [[ -n "${line}" ]]; then
  4763. defaultBase64Code vlessgrpc "${currentDefaultPort}" "${email}${count}" "$(echo "${user}" | jq -r .id)" "${line}"
  4764. count=$((count + 1))
  4765. fi
  4766. done < <(echo "${currentCDNAddress}" | tr ',' '\n')
  4767. done
  4768. fi
  4769. # hysteria2
  4770. if echo ${currentInstallProtocolType} | grep -q ",6," || [[ -n "${hysteriaPort}" ]]; then
  4771. readPortHopping "hysteria2" "${singBoxHysteria2Port}"
  4772. echoContent skyBlue "\n================================ Hysteria2 TLS [推荐] ================================\n"
  4773. local path="${configPath}"
  4774. if [[ "${coreInstallType}" == "1" ]]; then
  4775. path="${singBoxConfigPath}"
  4776. fi
  4777. local hysteria2DefaultPort=
  4778. if [[ -n "${hysteria2PortHoppingStart}" && -n "${hysteria2PortHoppingEnd}" ]]; then
  4779. hysteria2DefaultPort="${hysteria2PortHopping}"
  4780. else
  4781. hysteria2DefaultPort=${singBoxHysteria2Port}
  4782. fi
  4783. jq -r -c '.inbounds[]|.users[]' "${path}06_hysteria2_inbounds.json" | while read -r user; do
  4784. echoContent skyBlue "\n ---> 账号:$(echo "${user}" | jq -r .name)"
  4785. echo
  4786. defaultBase64Code hysteria "${hysteria2DefaultPort}" "$(echo "${user}" | jq -r .name)" "$(echo "${user}" | jq -r .password)"
  4787. done
  4788. fi
  4789. # VLESS reality vision
  4790. if echo ${currentInstallProtocolType} | grep -q ",7,"; then
  4791. echoContent skyBlue "============================= VLESS reality_vision [推荐] ==============================\n"
  4792. jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}07_VLESS_vision_reality_inbounds.json | jq -c '.[]' | while read -r user; do
  4793. local email=
  4794. email=$(echo "${user}" | jq -r .email//.name)
  4795. echoContent skyBlue "\n ---> 账号:${email}"
  4796. echo
  4797. defaultBase64Code vlessReality "${xrayVLESSRealityVisionPort}${singBoxVLESSRealityVisionPort}" "${email}" "$(echo "${user}" | jq -r .id//.uuid)"
  4798. done
  4799. fi
  4800. # VLESS reality gRPC
  4801. if echo ${currentInstallProtocolType} | grep -q ",8,"; then
  4802. echoContent skyBlue "============================== VLESS reality_gRPC [推荐] ===============================\n"
  4803. jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}08_VLESS_vision_gRPC_inbounds.json | jq -c '.[]' | while read -r user; do
  4804. local email=
  4805. email=$(echo "${user}" | jq -r .email//.name)
  4806. echoContent skyBlue "\n ---> 账号:${email}"
  4807. echo
  4808. defaultBase64Code vlessRealityGRPC "${xrayVLESSRealityVisionPort}${singBoxVLESSRealityGRPCPort}" "${email}" "$(echo "${user}" | jq -r .id//.uuid)"
  4809. done
  4810. fi
  4811. # tuic
  4812. if echo ${currentInstallProtocolType} | grep -q ",9," || [[ -n "${tuicPort}" ]]; then
  4813. echoContent skyBlue "\n================================ Tuic TLS [推荐] ================================\n"
  4814. local path="${configPath}"
  4815. if [[ "${coreInstallType}" == "1" ]]; then
  4816. path="${singBoxConfigPath}"
  4817. fi
  4818. jq -r -c '.inbounds[].users[]' "${path}09_tuic_inbounds.json" | while read -r user; do
  4819. echoContent skyBlue "\n ---> 账号:$(echo "${user}" | jq -r .name)"
  4820. echo
  4821. defaultBase64Code tuic "${singBoxTuicPort}" "$(echo "${user}" | jq -r .name)" "$(echo "${user}" | jq -r .uuid)_$(echo "${user}" | jq -r .password)"
  4822. done
  4823. fi
  4824. # naive
  4825. if echo ${currentInstallProtocolType} | grep -q ",10," || [[ -n "${singBoxNaivePort}" ]]; then
  4826. echoContent skyBlue "\n================================ naive TLS [推荐,不支持ClashMeta] ================================\n"
  4827. jq -r -c '.inbounds[]|.users[]' "${configPath}10_naive_inbounds.json" | while read -r user; do
  4828. echoContent skyBlue "\n ---> 账号:$(echo "${user}" | jq -r .username)"
  4829. echo
  4830. defaultBase64Code naive "${singBoxNaivePort}" "$(echo "${user}" | jq -r .username)" "$(echo "${user}" | jq -r .password)"
  4831. done
  4832. fi
  4833. # VMess HTTPUpgrade
  4834. if echo ${currentInstallProtocolType} | grep -q ",11,"; then
  4835. echoContent skyBlue "\n================================ VMess HTTPUpgrade TLS [仅CDN推荐] ================================\n"
  4836. local path="${currentPath}vws"
  4837. if [[ ${coreInstallType} == "1" ]]; then
  4838. path="/${currentPath}vws"
  4839. elif [[ "${coreInstallType}" == "2" ]]; then
  4840. path="${singBoxVMessHTTPUpgradePath}"
  4841. fi
  4842. jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}11_VMess_HTTPUpgrade_inbounds.json | jq -c '.[]' | while read -r user; do
  4843. local email=
  4844. email=$(echo "${user}" | jq -r .email//.name)
  4845. local vmessHTTPUpgradePort=${currentDefaultPort}
  4846. if [[ "${coreInstallType}" == "2" ]]; then
  4847. vmessHTTPUpgradePort="${singBoxVMessHTTPUpgradePort}"
  4848. fi
  4849. local count=
  4850. while read -r line; do
  4851. echoContent skyBlue "\n ---> 账号:${email}${count}"
  4852. echo
  4853. if [[ -n "${line}" ]]; then
  4854. defaultBase64Code vmessHTTPUpgrade "${vmessHTTPUpgradePort}" "${email}${count}" "$(echo "${user}" | jq -r .id//.uuid)" "${line}" "${path}"
  4855. count=$((count + 1))
  4856. fi
  4857. done < <(echo "${currentCDNAddress}" | tr ',' '\n')
  4858. done
  4859. fi
  4860. # VLESS XHTTP
  4861. if echo ${currentInstallProtocolType} | grep -q ",12,"; then
  4862. echoContent skyBlue "\n================================ VLESS XHTTP TLS [仅CDN推荐] ================================\n"
  4863. jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}12_VLESS_XHTTP_inbounds.json | jq -c '.[]' | while read -r user; do
  4864. local email=
  4865. email=$(echo "${user}" | jq -r .email//.name)
  4866. echo
  4867. local path="${currentPath}xHTTP"
  4868. local count=
  4869. while read -r line; do
  4870. echoContent skyBlue "\n ---> 账号:${email}${count}"
  4871. if [[ -n "${line}" ]]; then
  4872. defaultBase64Code vlessXHTTP "${xrayVLESSRealityXHTTPort}" "${email}${count}" "$(echo "${user}" | jq -r .id//.uuid)" "${line}" "${path}"
  4873. count=$((count + 1))
  4874. echo
  4875. fi
  4876. done < <(echo "${currentCDNAddress}" | tr ',' '\n')
  4877. done
  4878. fi
  4879. # AnyTLS
  4880. if echo ${currentInstallProtocolType} | grep -q ",13,"; then
  4881. echoContent skyBlue "\n================================ AnyTLS ================================\n"
  4882. jq -r -c '.inbounds[]|.users[]' "${configPath}13_anytls_inbounds.json" | while read -r user; do
  4883. echoContent skyBlue "\n ---> 账号:$(echo "${user}" | jq -r .name)"
  4884. echo
  4885. defaultBase64Code anytls "${singBoxAnyTLSPort}" "$(echo "${user}" | jq -r .name)" "$(echo "${user}" | jq -r .password)"
  4886. done
  4887. fi
  4888. }
  4889. # 移除nginx302配置
  4890. removeNginx302() {
  4891. local count=
  4892. grep -n "return 302" <"${nginxConfigPath}alone.conf" | while read -r line; do
  4893. if ! echo "${line}" | grep -q "request_uri"; then
  4894. local removeIndex=
  4895. removeIndex=$(echo "${line}" | awk -F "[:]" '{print $1}')
  4896. removeIndex=$((removeIndex + count))
  4897. sed -i "${removeIndex}d" ${nginxConfigPath}alone.conf
  4898. count=$((count - 1))
  4899. fi
  4900. done
  4901. }
  4902. # 检查302是否成功
  4903. checkNginx302() {
  4904. local domain302Status=
  4905. domain302Status=$(curl -s "https://${currentHost}:${currentPort}")
  4906. if echo "${domain302Status}" | grep -q "302"; then
  4907. # local domain302Result=
  4908. # domain302Result=$(curl -L -s "https://${currentHost}:${currentPort}")
  4909. # if [[ -n "${domain302Result}" ]]; then
  4910. echoContent green " ---> 302重定向设置完毕"
  4911. exit 0
  4912. # fi
  4913. fi
  4914. echoContent red " ---> 302重定向设置失败,请仔细检查是否和示例相同"
  4915. backupNginxConfig restoreBackup
  4916. }
  4917. # 备份恢复nginx文件
  4918. backupNginxConfig() {
  4919. if [[ "$1" == "backup" ]]; then
  4920. cp ${nginxConfigPath}alone.conf /etc/v2ray-agent/alone_backup.conf
  4921. echoContent green " ---> nginx配置文件备份成功"
  4922. fi
  4923. if [[ "$1" == "restoreBackup" ]] && [[ -f "/etc/v2ray-agent/alone_backup.conf" ]]; then
  4924. cp /etc/v2ray-agent/alone_backup.conf ${nginxConfigPath}alone.conf
  4925. echoContent green " ---> nginx配置文件恢复备份成功"
  4926. rm /etc/v2ray-agent/alone_backup.conf
  4927. fi
  4928. }
  4929. # 添加302配置
  4930. addNginx302() {
  4931. local count=1
  4932. grep -n "location / {" <"${nginxConfigPath}alone.conf" | while read -r line; do
  4933. if [[ -n "${line}" ]]; then
  4934. local insertIndex=
  4935. insertIndex="$(echo "${line}" | awk -F "[:]" '{print $1}')"
  4936. insertIndex=$((insertIndex + count))
  4937. sed "${insertIndex}i return 302 '$1';" ${nginxConfigPath}alone.conf >${nginxConfigPath}tmpfile && mv ${nginxConfigPath}tmpfile ${nginxConfigPath}alone.conf
  4938. count=$((count + 1))
  4939. else
  4940. echoContent red " ---> 302添加失败"
  4941. backupNginxConfig restoreBackup
  4942. fi
  4943. done
  4944. }
  4945. # 更新伪装站
  4946. updateNginxBlog() {
  4947. if [[ "${coreInstallType}" == "2" ]]; then
  4948. echoContent red "\n ---> 此功能仅支持Xray-core内核"
  4949. exit 0
  4950. fi
  4951. echoContent skyBlue "\n进度 $1/${totalProgress} : 更换伪装站点"
  4952. if ! echo "${currentInstallProtocolType}" | grep -q ",0," || [[ -z "${coreInstallType}" ]]; then
  4953. echoContent red "\n ---> 由于环境依赖,请先安装Xray-core的VLESS_TCP_TLS_Vision"
  4954. exit 0
  4955. fi
  4956. echoContent red "=============================================================="
  4957. echoContent yellow "# 如需自定义,请手动复制模版文件到 ${nginxStaticPath} \n"
  4958. echoContent yellow "1.新手引导"
  4959. echoContent yellow "2.游戏网站"
  4960. echoContent yellow "3.个人博客01"
  4961. echoContent yellow "4.企业站"
  4962. echoContent yellow "5.解锁加密的音乐文件模版[https://github.com/ix64/unlock-music]"
  4963. echoContent yellow "6.mikutap[https://github.com/HFIProgramming/mikutap]"
  4964. echoContent yellow "7.企业站02"
  4965. echoContent yellow "8.个人博客02"
  4966. echoContent yellow "9.404自动跳转baidu"
  4967. echoContent yellow "10.302重定向网站"
  4968. echoContent red "=============================================================="
  4969. read -r -p "请选择:" selectInstallNginxBlogType
  4970. if [[ "${selectInstallNginxBlogType}" == "10" ]]; then
  4971. if [[ "${coreInstallType}" == "2" ]]; then
  4972. echoContent red "\n ---> 此功能仅支持Xray-core内核,请等待后续更新"
  4973. exit 0
  4974. fi
  4975. echoContent red "\n=============================================================="
  4976. echoContent yellow "重定向的优先级更高,配置302之后如果更改伪装站点,根路由下伪装站点将不起作用"
  4977. echoContent yellow "如想要伪装站点实现作用需删除302重定向配置\n"
  4978. echoContent yellow "1.添加"
  4979. echoContent yellow "2.删除"
  4980. echoContent red "=============================================================="
  4981. read -r -p "请选择:" redirectStatus
  4982. if [[ "${redirectStatus}" == "1" ]]; then
  4983. backupNginxConfig backup
  4984. read -r -p "请输入要重定向的域名,例如 https://www.baidu.com:" redirectDomain
  4985. removeNginx302
  4986. addNginx302 "${redirectDomain}"
  4987. handleNginx stop
  4988. handleNginx start
  4989. if [[ -z $(pgrep -f "nginx") ]]; then
  4990. backupNginxConfig restoreBackup
  4991. handleNginx start
  4992. exit 0
  4993. fi
  4994. checkNginx302
  4995. exit 0
  4996. fi
  4997. if [[ "${redirectStatus}" == "2" ]]; then
  4998. removeNginx302
  4999. echoContent green " ---> 移除302重定向成功"
  5000. exit 0
  5001. fi
  5002. fi
  5003. if [[ "${selectInstallNginxBlogType}" =~ ^[1-9]$ ]]; then
  5004. rm -rf "${nginxStaticPath}*"
  5005. if [[ "${release}" == "alpine" ]]; then
  5006. wget -q -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${selectInstallNginxBlogType}.zip"
  5007. else
  5008. wget -q "${wgetShowProgressStatus}" -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${selectInstallNginxBlogType}.zip"
  5009. fi
  5010. unzip -o "${nginxStaticPath}html${selectInstallNginxBlogType}.zip" -d "${nginxStaticPath}" >/dev/null
  5011. rm -f "${nginxStaticPath}html${selectInstallNginxBlogType}.zip*"
  5012. echoContent green " ---> 更换伪站成功"
  5013. else
  5014. echoContent red " ---> 选择错误,请重新选择"
  5015. updateNginxBlog
  5016. fi
  5017. }
  5018. # 添加新端口
  5019. addCorePort() {
  5020. if [[ "${coreInstallType}" == "2" ]]; then
  5021. echoContent red "\n ---> 此功能仅支持Xray-core内核"
  5022. exit 0
  5023. fi
  5024. echoContent skyBlue "\n功能 1/${totalProgress} : 添加新端口"
  5025. echoContent red "\n=============================================================="
  5026. echoContent yellow "# 注意事项\n"
  5027. echoContent yellow "支持批量添加"
  5028. echoContent yellow "不影响默认端口的使用"
  5029. echoContent yellow "查看账号时,只会展示默认端口的账号"
  5030. echoContent yellow "不允许有特殊字符,注意逗号的格式"
  5031. echoContent yellow "如已安装hysteria,会同时安装hysteria新端口"
  5032. echoContent yellow "录入示例:2053,2083,2087\n"
  5033. echoContent yellow "1.查看已添加端口"
  5034. echoContent yellow "2.添加端口"
  5035. echoContent yellow "3.删除端口"
  5036. echoContent red "=============================================================="
  5037. read -r -p "请选择:" selectNewPortType
  5038. if [[ "${selectNewPortType}" == "1" ]]; then
  5039. find ${configPath} -name "*dokodemodoor*" | grep -v "hysteria" | awk -F "[c][o][n][f][/]" '{print $2}' | awk -F "[_]" '{print $4}' | awk -F "[.]" '{print ""NR""":"$1}'
  5040. exit 0
  5041. elif [[ "${selectNewPortType}" == "2" ]]; then
  5042. read -r -p "请输入端口号:" newPort
  5043. read -r -p "请输入默认的端口号,同时会更改订阅端口以及节点端口,[回车]默认443:" defaultPort
  5044. if [[ -n "${defaultPort}" ]]; then
  5045. rm -rf "$(find ${configPath}* | grep "default")"
  5046. fi
  5047. if [[ -n "${newPort}" ]]; then
  5048. while read -r port; do
  5049. rm -rf "$(find ${configPath}* | grep "${port}")"
  5050. local fileName=
  5051. local hysteriaFileName=
  5052. if [[ -n "${defaultPort}" && "${port}" == "${defaultPort}" ]]; then
  5053. fileName="${configPath}02_dokodemodoor_inbounds_${port}_default.json"
  5054. else
  5055. fileName="${configPath}02_dokodemodoor_inbounds_${port}.json"
  5056. fi
  5057. if [[ -n ${hysteriaPort} ]]; then
  5058. hysteriaFileName="${configPath}02_dokodemodoor_inbounds_hysteria_${port}.json"
  5059. fi
  5060. # 开放端口
  5061. allowPort "${port}"
  5062. allowPort "${port}" "udp"
  5063. local settingsPort=443
  5064. if [[ -n "${customPort}" ]]; then
  5065. settingsPort=${customPort}
  5066. fi
  5067. if [[ -n ${hysteriaFileName} ]]; then
  5068. cat <<EOF >"${hysteriaFileName}"
  5069. {
  5070. "inbounds": [
  5071. {
  5072. "listen": "0.0.0.0",
  5073. "port": ${port},
  5074. "protocol": "dokodemo-door",
  5075. "settings": {
  5076. "address": "127.0.0.1",
  5077. "port": ${hysteriaPort},
  5078. "network": "udp",
  5079. "followRedirect": false
  5080. },
  5081. "tag": "dokodemo-door-newPort-hysteria-${port}"
  5082. }
  5083. ]
  5084. }
  5085. EOF
  5086. fi
  5087. cat <<EOF >"${fileName}"
  5088. {
  5089. "inbounds": [
  5090. {
  5091. "listen": "0.0.0.0",
  5092. "port": ${port},
  5093. "protocol": "dokodemo-door",
  5094. "settings": {
  5095. "address": "127.0.0.1",
  5096. "port": ${settingsPort},
  5097. "network": "tcp",
  5098. "followRedirect": false
  5099. },
  5100. "tag": "dokodemo-door-newPort-${port}"
  5101. }
  5102. ]
  5103. }
  5104. EOF
  5105. done < <(echo "${newPort}" | tr ',' '\n')
  5106. echoContent green " ---> 添加完毕"
  5107. reloadCore
  5108. addCorePort
  5109. fi
  5110. elif [[ "${selectNewPortType}" == "3" ]]; then
  5111. find ${configPath} -name "*dokodemodoor*" | grep -v "hysteria" | awk -F "[c][o][n][f][/]" '{print $2}' | awk -F "[_]" '{print $4}' | awk -F "[.]" '{print ""NR""":"$1}'
  5112. read -r -p "请输入要删除的端口编号:" portIndex
  5113. local dokoConfig
  5114. dokoConfig=$(find ${configPath} -name "*dokodemodoor*" | grep -v "hysteria" | awk -F "[c][o][n][f][/]" '{print $2}' | awk -F "[_]" '{print $4}' | awk -F "[.]" '{print ""NR""":"$1}' | grep "${portIndex}:")
  5115. if [[ -n "${dokoConfig}" ]]; then
  5116. rm "${configPath}02_dokodemodoor_inbounds_$(echo "${dokoConfig}" | awk -F "[:]" '{print $2}').json"
  5117. local hysteriaDokodemodoorFilePath=
  5118. hysteriaDokodemodoorFilePath="${configPath}02_dokodemodoor_inbounds_hysteria_$(echo "${dokoConfig}" | awk -F "[:]" '{print $2}').json"
  5119. if [[ -f "${hysteriaDokodemodoorFilePath}" ]]; then
  5120. rm "${hysteriaDokodemodoorFilePath}"
  5121. fi
  5122. reloadCore
  5123. addCorePort
  5124. else
  5125. echoContent yellow "\n ---> 编号输入错误,请重新选择"
  5126. addCorePort
  5127. fi
  5128. fi
  5129. }
  5130. # 卸载脚本
  5131. unInstall() {
  5132. read -r -p "是否确认卸载安装内容?[y/n]:" unInstallStatus
  5133. if [[ "${unInstallStatus}" != "y" ]]; then
  5134. echoContent green " ---> 放弃卸载"
  5135. menu
  5136. exit 0
  5137. fi
  5138. checkBTPanel
  5139. echoContent yellow " ---> 脚本不会删除acme相关配置,删除请手动执行 [rm -rf /root/.acme.sh]"
  5140. handleNginx stop
  5141. if [[ -z $(pgrep -f "nginx") ]]; then
  5142. echoContent green " ---> 停止Nginx成功"
  5143. fi
  5144. if [[ "${release}" == "alpine" ]]; then
  5145. if [[ "${coreInstallType}" == "1" ]]; then
  5146. handleXray stop
  5147. rc-update del xray default
  5148. rm -rf /etc/init.d/xray
  5149. echoContent green " ---> 删除Xray开机自启完成"
  5150. fi
  5151. if [[ "${coreInstallType}" == "2" || -n "${singBoxConfigPath}" ]]; then
  5152. handleSingBox stop
  5153. rc-update del sing-box default
  5154. rm -rf /etc/init.d/sing-box
  5155. echoContent green " ---> 删除sing-box开机自启完成"
  5156. fi
  5157. else
  5158. if [[ "${coreInstallType}" == "1" ]]; then
  5159. handleXray stop
  5160. rm -rf /etc/systemd/system/xray.service
  5161. echoContent green " ---> 删除Xray开机自启完成"
  5162. fi
  5163. if [[ "${coreInstallType}" == "2" || -n "${singBoxConfigPath}" ]]; then
  5164. handleSingBox stop
  5165. rm -rf /etc/systemd/system/sing-box.service
  5166. echoContent green " ---> 删除sing-box开机自启完成"
  5167. fi
  5168. fi
  5169. rm -rf /etc/v2ray-agent
  5170. rm -rf ${nginxConfigPath}alone.conf
  5171. rm -rf ${nginxConfigPath}checkPortOpen.conf >/dev/null 2>&1
  5172. rm -rf "${nginxConfigPath}sing_box_VMess_HTTPUpgrade.conf" >/dev/null 2>&1
  5173. rm -rf ${nginxConfigPath}checkPortOpen.conf >/dev/null 2>&1
  5174. unInstallSubscribe
  5175. if [[ -d "${nginxStaticPath}" && -f "${nginxStaticPath}/check" ]]; then
  5176. rm -rf "${nginxStaticPath}"
  5177. echoContent green " ---> 删除伪装网站完成"
  5178. fi
  5179. rm -rf /usr/bin/vasma
  5180. rm -rf /usr/sbin/vasma
  5181. echoContent green " ---> 卸载快捷方式完成"
  5182. echoContent green " ---> 卸载v2ray-agent脚本完成"
  5183. }
  5184. # CDN节点管理
  5185. manageCDN() {
  5186. echoContent skyBlue "\n进度 $1/1 : CDN节点管理"
  5187. local setCDNDomain=
  5188. if echo "${currentInstallProtocolType}" | grep -qE ",1,|,2,|,3,|,5,|,11,"; then
  5189. echoContent red "=============================================================="
  5190. echoContent yellow "# 注意事项"
  5191. echoContent yellow "\n教程地址:"
  5192. echoContent skyBlue "https://www.v2ray-agent.com/archives/cloudflarezi-xuan-ip"
  5193. echoContent red "\n如对Cloudflare优化不了解,请不要使用"
  5194. echoContent yellow "1.CNAME www.digitalocean.com"
  5195. echoContent yellow "2.CNAME who.int"
  5196. echoContent yellow "3.CNAME blog.hostmonit.com"
  5197. echoContent yellow "4.CNAME www.visa.com.hk"
  5198. echoContent yellow "5.手动输入[可输入多个,比如: 1.1.1.1,1.1.2.2,cloudflare.com 逗号分隔]"
  5199. echoContent yellow "6.移除CDN节点"
  5200. echoContent red "=============================================================="
  5201. read -r -p "请选择:" selectCDNType
  5202. case ${selectCDNType} in
  5203. 1)
  5204. setCDNDomain="www.digitalocean.com"
  5205. ;;
  5206. 2)
  5207. setCDNDomain="who.int"
  5208. ;;
  5209. 3)
  5210. setCDNDomain="blog.hostmonit.com"
  5211. ;;
  5212. 4)
  5213. setCDNDomain="www.visa.com.hk"
  5214. ;;
  5215. 5)
  5216. read -r -p "请输入想要自定义CDN IP或者域名:" setCDNDomain
  5217. ;;
  5218. 6)
  5219. echo >/etc/v2ray-agent/cdn
  5220. echoContent green " ---> 移除成功"
  5221. exit 0
  5222. ;;
  5223. esac
  5224. if [[ -n "${setCDNDomain}" ]]; then
  5225. echo >/etc/v2ray-agent/cdn
  5226. echo "${setCDNDomain}" >"/etc/v2ray-agent/cdn"
  5227. echoContent green " ---> 修改CDN成功"
  5228. subscribe false false
  5229. else
  5230. echoContent red " ---> 不可以为空,请重新输入"
  5231. manageCDN 1
  5232. fi
  5233. else
  5234. echoContent yellow "\n教程地址:"
  5235. echoContent skyBlue "https://www.v2ray-agent.com/archives/cloudflarezi-xuan-ip\n"
  5236. echoContent red " ---> 未检测到可以使用的协议,仅支持ws、grpc、HTTPUpgrade相关的协议"
  5237. fi
  5238. }
  5239. # 自定义uuid
  5240. customUUID() {
  5241. read -r -p "请输入合法的UUID,[回车]随机UUID:" currentCustomUUID
  5242. echo
  5243. if [[ -z "${currentCustomUUID}" ]]; then
  5244. if [[ "${selectInstallType}" == "1" || "${coreInstallType}" == "1" ]]; then
  5245. currentCustomUUID=$(${ctlPath} uuid)
  5246. elif [[ "${selectInstallType}" == "2" || "${coreInstallType}" == "2" ]]; then
  5247. currentCustomUUID=$(${ctlPath} generate uuid)
  5248. fi
  5249. echoContent yellow "uuid:${currentCustomUUID}\n"
  5250. else
  5251. local checkUUID=
  5252. if [[ "${coreInstallType}" == "1" ]]; then
  5253. checkUUID=$(jq -r --arg currentUUID "$currentCustomUUID" ".inbounds[0].settings.clients[] | select(.uuid | index(\$currentUUID) != null) | .name" ${configPath}${frontingType}.json)
  5254. elif [[ "${coreInstallType}" == "2" ]]; then
  5255. checkUUID=$(jq -r --arg currentUUID "$currentCustomUUID" ".inbounds[0].users[] | select(.uuid | index(\$currentUUID) != null) | .name//.username" ${configPath}${frontingType}.json)
  5256. fi
  5257. if [[ -n "${checkUUID}" ]]; then
  5258. echoContent red " ---> UUID不可重复"
  5259. exit 0
  5260. fi
  5261. fi
  5262. }
  5263. # 自定义email
  5264. customUserEmail() {
  5265. read -r -p "请输入合法的email,[回车]随机email:" currentCustomEmail
  5266. echo
  5267. if [[ -z "${currentCustomEmail}" ]]; then
  5268. currentCustomEmail="${currentCustomUUID}"
  5269. echoContent yellow "email: ${currentCustomEmail}\n"
  5270. else
  5271. local checkEmail=
  5272. if [[ "${coreInstallType}" == "1" ]]; then
  5273. local frontingTypeConfig="${frontingType}"
  5274. if [[ "${currentInstallProtocolType}" == ",7,8," ]]; then
  5275. frontingTypeConfig="07_VLESS_vision_reality_inbounds"
  5276. fi
  5277. checkEmail=$(jq -r --arg currentEmail "$currentCustomEmail" ".inbounds[0].settings.clients[] | select(.name | index(\$currentEmail) != null) | .name" ${configPath}${frontingTypeConfig}.json)
  5278. elif
  5279. [[ "${coreInstallType}" == "2" ]]
  5280. then
  5281. checkEmail=$(jq -r --arg currentEmail "$currentCustomEmail" ".inbounds[0].users[] | select(.name | index(\$currentEmail) != null) | .name" ${configPath}${frontingType}.json)
  5282. fi
  5283. if [[ -n "${checkEmail}" ]]; then
  5284. echoContent red " ---> email不可重复"
  5285. exit 0
  5286. fi
  5287. fi
  5288. }
  5289. # 添加用户
  5290. addUser() {
  5291. read -r -p "请输入要添加的用户数量:" userNum
  5292. echo
  5293. if [[ -z ${userNum} || ${userNum} -le 0 ]]; then
  5294. echoContent red " ---> 输入有误,请重新输入"
  5295. exit 0
  5296. fi
  5297. local userConfig=
  5298. if [[ "${coreInstallType}" == "1" ]]; then
  5299. userConfig=".inbounds[0].settings.clients"
  5300. elif [[ "${coreInstallType}" == "2" ]]; then
  5301. userConfig=".inbounds[0].users"
  5302. fi
  5303. while [[ ${userNum} -gt 0 ]]; do
  5304. readConfigHostPathUUID
  5305. local users=
  5306. ((userNum--)) || true
  5307. customUUID
  5308. customUserEmail
  5309. uuid=${currentCustomUUID}
  5310. email=${currentCustomEmail}
  5311. # VLESS TCP
  5312. if echo "${currentInstallProtocolType}" | grep -q ",0,"; then
  5313. local clients=
  5314. if [[ "${coreInstallType}" == "1" ]]; then
  5315. clients=$(initXrayClients 0 "${uuid}" "${email}")
  5316. elif [[ "${coreInstallType}" == "2" ]]; then
  5317. clients=$(initSingBoxClients 0 "${uuid}" "${email}")
  5318. fi
  5319. clients=$(jq -r "${userConfig} = ${clients}" ${configPath}02_VLESS_TCP_inbounds.json)
  5320. echo "${clients}" | jq . >${configPath}02_VLESS_TCP_inbounds.json
  5321. fi
  5322. # VLESS WS
  5323. if echo "${currentInstallProtocolType}" | grep -q ",1,"; then
  5324. local clients=
  5325. if [[ "${coreInstallType}" == "1" ]]; then
  5326. clients=$(initXrayClients 1 "${uuid}" "${email}")
  5327. elif [[ "${coreInstallType}" == "2" ]]; then
  5328. clients=$(initSingBoxClients 1 "${uuid}" "${email}")
  5329. fi
  5330. clients=$(jq -r "${userConfig} = ${clients}" ${configPath}03_VLESS_WS_inbounds.json)
  5331. echo "${clients}" | jq . >${configPath}03_VLESS_WS_inbounds.json
  5332. fi
  5333. # trojan grpc
  5334. if echo "${currentInstallProtocolType}" | grep -q ",2,"; then
  5335. local clients=
  5336. if [[ "${coreInstallType}" == "1" ]]; then
  5337. clients=$(initXrayClients 2 "${uuid}" "${email}")
  5338. elif [[ "${coreInstallType}" == "2" ]]; then
  5339. clients=$(initSingBoxClients 2 "${uuid}" "${email}")
  5340. fi
  5341. clients=$(jq -r "${userConfig} = ${clients}" ${configPath}04_trojan_gRPC_inbounds.json)
  5342. echo "${clients}" | jq . >${configPath}04_trojan_gRPC_inbounds.json
  5343. fi
  5344. # VMess WS
  5345. if echo "${currentInstallProtocolType}" | grep -q ",3,"; then
  5346. local clients=
  5347. if [[ "${coreInstallType}" == "1" ]]; then
  5348. clients=$(initXrayClients 3 "${uuid}" "${email}")
  5349. elif [[ "${coreInstallType}" == "2" ]]; then
  5350. clients=$(initSingBoxClients 3 "${uuid}" "${email}")
  5351. fi
  5352. clients=$(jq -r "${userConfig} = ${clients}" ${configPath}05_VMess_WS_inbounds.json)
  5353. echo "${clients}" | jq . >${configPath}05_VMess_WS_inbounds.json
  5354. fi
  5355. # trojan tcp
  5356. if echo "${currentInstallProtocolType}" | grep -q ",4,"; then
  5357. local clients=
  5358. if [[ "${coreInstallType}" == "1" ]]; then
  5359. clients=$(initXrayClients 4 "${uuid}" "${email}")
  5360. elif [[ "${coreInstallType}" == "2" ]]; then
  5361. clients=$(initSingBoxClients 4 "${uuid}" "${email}")
  5362. fi
  5363. clients=$(jq -r "${userConfig} = ${clients}" ${configPath}04_trojan_TCP_inbounds.json)
  5364. echo "${clients}" | jq . >${configPath}04_trojan_TCP_inbounds.json
  5365. fi
  5366. # vless grpc
  5367. if echo "${currentInstallProtocolType}" | grep -q ",5,"; then
  5368. local clients=
  5369. if [[ "${coreInstallType}" == "1" ]]; then
  5370. clients=$(initXrayClients 5 "${uuid}" "${email}")
  5371. elif [[ "${coreInstallType}" == "2" ]]; then
  5372. clients=$(initSingBoxClients 5 "${uuid}" "${email}")
  5373. fi
  5374. clients=$(jq -r "${userConfig} = ${clients}" ${configPath}06_VLESS_gRPC_inbounds.json)
  5375. echo "${clients}" | jq . >${configPath}06_VLESS_gRPC_inbounds.json
  5376. fi
  5377. # vless reality vision
  5378. if echo "${currentInstallProtocolType}" | grep -q ",7,"; then
  5379. local clients=
  5380. if [[ "${coreInstallType}" == "1" ]]; then
  5381. clients=$(initXrayClients 7 "${uuid}" "${email}")
  5382. elif [[ "${coreInstallType}" == "2" ]]; then
  5383. clients=$(initSingBoxClients 7 "${uuid}" "${email}")
  5384. fi
  5385. clients=$(jq -r "${userConfig} = ${clients}" ${configPath}07_VLESS_vision_reality_inbounds.json)
  5386. echo "${clients}" | jq . >${configPath}07_VLESS_vision_reality_inbounds.json
  5387. fi
  5388. # vless reality grpc
  5389. if echo "${currentInstallProtocolType}" | grep -q ",8,"; then
  5390. local clients=
  5391. if [[ "${coreInstallType}" == "1" ]]; then
  5392. clients=$(initXrayClients 8 "${uuid}" "${email}")
  5393. elif [[ "${coreInstallType}" == "2" ]]; then
  5394. clients=$(initSingBoxClients 8 "${uuid}" "${email}")
  5395. fi
  5396. clients=$(jq -r "${userConfig} = ${clients}" ${configPath}08_VLESS_vision_gRPC_inbounds.json)
  5397. echo "${clients}" | jq . >${configPath}08_VLESS_vision_gRPC_inbounds.json
  5398. fi
  5399. # hysteria2
  5400. if echo ${currentInstallProtocolType} | grep -q ",6,"; then
  5401. local clients=
  5402. if [[ "${coreInstallType}" == "1" ]]; then
  5403. clients=$(initXrayClients 6 "${uuid}" "${email}")
  5404. elif [[ -n "${singBoxConfigPath}" ]]; then
  5405. clients=$(initSingBoxClients 6 "${uuid}" "${email}")
  5406. fi
  5407. clients=$(jq -r ".inbounds[0].users = ${clients}" "${singBoxConfigPath}06_hysteria2_inbounds.json")
  5408. echo "${clients}" | jq . >"${singBoxConfigPath}06_hysteria2_inbounds.json"
  5409. fi
  5410. # tuic
  5411. if echo ${currentInstallProtocolType} | grep -q ",9,"; then
  5412. local clients=
  5413. if [[ "${coreInstallType}" == "1" ]]; then
  5414. clients=$(initXrayClients 9 "${uuid}" "${email}")
  5415. elif [[ "${coreInstallType}" == "2" ]]; then
  5416. clients=$(initSingBoxClients 9 "${uuid}" "${email}")
  5417. fi
  5418. clients=$(jq -r ".inbounds[0].users = ${clients}" "${singBoxConfigPath}09_tuic_inbounds.json")
  5419. echo "${clients}" | jq . >"${singBoxConfigPath}09_tuic_inbounds.json"
  5420. fi
  5421. # naive
  5422. if echo ${currentInstallProtocolType} | grep -q ",10,"; then
  5423. local clients=
  5424. clients=$(initSingBoxClients 10 "${uuid}" "${email}")
  5425. clients=$(jq -r ".inbounds[0].users = ${clients}" "${singBoxConfigPath}10_naive_inbounds.json")
  5426. echo "${clients}" | jq . >"${singBoxConfigPath}10_naive_inbounds.json"
  5427. fi
  5428. # VMess WS
  5429. if echo "${currentInstallProtocolType}" | grep -q ",11,"; then
  5430. local clients=
  5431. if [[ "${coreInstallType}" == "1" ]]; then
  5432. clients=$(initXrayClients 11 "${uuid}" "${email}")
  5433. elif [[ "${coreInstallType}" == "2" ]]; then
  5434. clients=$(initSingBoxClients 11 "${uuid}" "${email}")
  5435. fi
  5436. clients=$(jq -r "${userConfig} = ${clients}" ${configPath}11_VMess_HTTPUpgrade_inbounds.json)
  5437. echo "${clients}" | jq . >${configPath}11_VMess_HTTPUpgrade_inbounds.json
  5438. fi
  5439. done
  5440. reloadCore
  5441. echoContent green " ---> 添加完成"
  5442. subscribe false
  5443. manageAccount 1
  5444. }
  5445. # 移除用户
  5446. removeUser() {
  5447. local userConfigType=
  5448. if [[ -n "${frontingType}" ]]; then
  5449. userConfigType="${frontingType}"
  5450. elif [[ -n "${frontingTypeReality}" ]]; then
  5451. userConfigType="${frontingTypeReality}"
  5452. fi
  5453. local uuid=
  5454. if [[ -n "${userConfigType}" ]]; then
  5455. if [[ "${coreInstallType}" == "1" ]]; then
  5456. jq -r -c .inbounds[0].settings.clients[].email ${configPath}${userConfigType}.json | awk '{print NR""":"$0}'
  5457. elif [[ "${coreInstallType}" == "2" ]]; then
  5458. jq -r -c .inbounds[0].users[].name//.inbounds[0].users[].username ${configPath}${userConfigType}.json | awk '{print NR""":"$0}'
  5459. fi
  5460. read -r -p "请选择要删除的用户编号[仅支持单个删除]:" delUserIndex
  5461. if [[ $(jq -r '.inbounds[0].settings.clients|length' ${configPath}${userConfigType}.json) -lt ${delUserIndex} && $(jq -r '.inbounds[0].users|length' ${configPath}${userConfigType}.json) -lt ${delUserIndex} ]]; then
  5462. echoContent red " ---> 选择错误"
  5463. else
  5464. delUserIndex=$((delUserIndex - 1))
  5465. fi
  5466. fi
  5467. if [[ -n "${delUserIndex}" ]]; then
  5468. if echo ${currentInstallProtocolType} | grep -q ",0,"; then
  5469. local vlessVision
  5470. vlessVision=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' ${configPath}02_VLESS_TCP_inbounds.json)
  5471. echo "${vlessVision}" | jq . >${configPath}02_VLESS_TCP_inbounds.json
  5472. fi
  5473. if echo ${currentInstallProtocolType} | grep -q ",1,"; then
  5474. local vlessWSResult
  5475. vlessWSResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}03_VLESS_WS_inbounds.json)
  5476. echo "${vlessWSResult}" | jq . >${configPath}03_VLESS_WS_inbounds.json
  5477. fi
  5478. if echo ${currentInstallProtocolType} | grep -q ",2,"; then
  5479. local trojangRPCUsers
  5480. trojangRPCUsers=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}04_trojan_gRPC_inbounds.json)
  5481. echo "${trojangRPCUsers}" | jq . >${configPath}04_trojan_gRPC_inbounds.json
  5482. fi
  5483. if echo ${currentInstallProtocolType} | grep -q ",3,"; then
  5484. local vmessWSResult
  5485. vmessWSResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' ${configPath}05_VMess_WS_inbounds.json)
  5486. echo "${vmessWSResult}" | jq . >${configPath}05_VMess_WS_inbounds.json
  5487. fi
  5488. if echo ${currentInstallProtocolType} | grep -q ",5,"; then
  5489. local vlessGRPCResult
  5490. vlessGRPCResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' ${configPath}06_VLESS_gRPC_inbounds.json)
  5491. echo "${vlessGRPCResult}" | jq . >${configPath}06_VLESS_gRPC_inbounds.json
  5492. fi
  5493. if echo ${currentInstallProtocolType} | grep -q ",4,"; then
  5494. local trojanTCPResult
  5495. trojanTCPResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' ${configPath}04_trojan_TCP_inbounds.json)
  5496. echo "${trojanTCPResult}" | jq . >${configPath}04_trojan_TCP_inbounds.json
  5497. fi
  5498. if echo ${currentInstallProtocolType} | grep -q ",7,"; then
  5499. local vlessRealityResult
  5500. vlessRealityResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' ${configPath}07_VLESS_vision_reality_inbounds.json)
  5501. echo "${vlessRealityResult}" | jq . >${configPath}07_VLESS_vision_reality_inbounds.json
  5502. fi
  5503. if echo ${currentInstallProtocolType} | grep -q ",8,"; then
  5504. local vlessRealityGRPCResult
  5505. vlessRealityGRPCResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' ${configPath}08_VLESS_vision_gRPC_inbounds.json)
  5506. echo "${vlessRealityGRPCResult}" | jq . >${configPath}08_VLESS_vision_gRPC_inbounds.json
  5507. fi
  5508. if echo ${currentInstallProtocolType} | grep -q ",6,"; then
  5509. local hysteriaResult
  5510. hysteriaResult=$(jq -r 'del(.inbounds[0].users['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' "${singBoxConfigPath}06_hysteria2_inbounds.json")
  5511. echo "${hysteriaResult}" | jq . >"${singBoxConfigPath}06_hysteria2_inbounds.json"
  5512. fi
  5513. if echo ${currentInstallProtocolType} | grep -q ",9,"; then
  5514. local tuicResult
  5515. tuicResult=$(jq -r 'del(.inbounds[0].users['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' "${singBoxConfigPath}09_tuic_inbounds.json")
  5516. echo "${tuicResult}" | jq . >"${singBoxConfigPath}09_tuic_inbounds.json"
  5517. fi
  5518. if echo ${currentInstallProtocolType} | grep -q ",10,"; then
  5519. local naiveResult
  5520. naiveResult=$(jq -r 'del(.inbounds[0].users['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' "${singBoxConfigPath}10_naive_inbounds.json")
  5521. echo "${naiveResult}" | jq . >"${singBoxConfigPath}10_naive_inbounds.json"
  5522. fi
  5523. # VMess HTTPUpgrade
  5524. if echo ${currentInstallProtocolType} | grep -q ",11,"; then
  5525. local vmessHTTPUpgradeResult
  5526. vmessHTTPUpgradeResult=$(jq -r 'del(.inbounds[0].users['${delUserIndex}']//.inbounds[0].users['${delUserIndex}'])' "${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json")
  5527. echo "${vmessHTTPUpgradeResult}" | jq . >"${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json"
  5528. echo "${vmessHTTPUpgradeResult}" | jq . >${configPath}11_VMess_HTTPUpgrade_inbounds.json
  5529. fi
  5530. reloadCore
  5531. subscribe false
  5532. fi
  5533. manageAccount 1
  5534. }
  5535. # 更新脚本
  5536. updateV2RayAgent() {
  5537. echoContent skyBlue "\n进度 $1/${totalProgress} : 更新v2ray-agent脚本"
  5538. rm -rf /etc/v2ray-agent/install.sh
  5539. if [[ "${release}" == "alpine" ]]; then
  5540. wget -c -q -P /etc/v2ray-agent/ -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh"
  5541. else
  5542. wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/ -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh"
  5543. fi
  5544. sudo chmod 700 /etc/v2ray-agent/install.sh
  5545. local version
  5546. version=$(grep '当前版本:v' "/etc/v2ray-agent/install.sh" | awk -F "[v]" '{print $2}' | tail -n +2 | head -n 1 | awk -F "[\"]" '{print $1}')
  5547. echoContent green "\n ---> 更新完毕"
  5548. echoContent yellow " ---> 请手动执行[vasma]打开脚本"
  5549. echoContent green " ---> 当前版本:${version}\n"
  5550. echoContent yellow "如更新不成功,请手动执行下面命令\n"
  5551. echoContent skyBlue "wget -P /root -N --no-check-certificate https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh && chmod 700 /root/install.sh && /root/install.sh"
  5552. echo
  5553. exit 0
  5554. }
  5555. # 防火墙
  5556. handleFirewall() {
  5557. if systemctl status ufw 2>/dev/null | grep -q "active (exited)" && [[ "$1" == "stop" ]]; then
  5558. systemctl stop ufw >/dev/null 2>&1
  5559. systemctl disable ufw >/dev/null 2>&1
  5560. echoContent green " ---> ufw关闭成功"
  5561. fi
  5562. if systemctl status firewalld 2>/dev/null | grep -q "active (running)" && [[ "$1" == "stop" ]]; then
  5563. systemctl stop firewalld >/dev/null 2>&1
  5564. systemctl disable firewalld >/dev/null 2>&1
  5565. echoContent green " ---> firewalld关闭成功"
  5566. fi
  5567. }
  5568. # 安装BBR
  5569. bbrInstall() {
  5570. echoContent red "\n=============================================================="
  5571. echoContent green "BBR、DD脚本用的[ylx2016]的成熟作品,地址[https://github.com/ylx2016/Linux-NetSpeed],请熟知"
  5572. echoContent yellow "1.安装脚本【推荐原版BBR+FQ】"
  5573. echoContent yellow "2.回退主目录"
  5574. echoContent red "=============================================================="
  5575. read -r -p "请选择:" installBBRStatus
  5576. if [[ "${installBBRStatus}" == "1" ]]; then
  5577. wget -N --no-check-certificate "https://raw.githubusercontent.com/ylx2016/Linux-NetSpeed/master/tcp.sh" && chmod +x tcp.sh && ./tcp.sh
  5578. else
  5579. menu
  5580. fi
  5581. }
  5582. # 查看、检查日志
  5583. checkLog() {
  5584. if [[ "${coreInstallType}" == "2" ]]; then
  5585. echoContent red "\n ---> 此功能仅支持Xray-core内核"
  5586. exit 0
  5587. fi
  5588. if [[ -z "${configPath}" && -z "${realityStatus}" ]]; then
  5589. echoContent red " ---> 没有检测到安装目录,请执行脚本安装内容"
  5590. exit 0
  5591. fi
  5592. local realityLogShow=
  5593. local logStatus=false
  5594. if grep -q "access" ${configPath}00_log.json; then
  5595. logStatus=true
  5596. fi
  5597. echoContent skyBlue "\n功能 $1/${totalProgress} : 查看日志"
  5598. echoContent red "\n=============================================================="
  5599. echoContent yellow "# 建议仅调试时打开access日志\n"
  5600. if [[ "${logStatus}" == "false" ]]; then
  5601. echoContent yellow "1.打开access日志"
  5602. else
  5603. echoContent yellow "1.关闭access日志"
  5604. fi
  5605. echoContent yellow "2.监听access日志"
  5606. echoContent yellow "3.监听error日志"
  5607. echoContent yellow "4.查看证书定时任务日志"
  5608. echoContent yellow "5.查看证书安装日志"
  5609. echoContent yellow "6.清空日志"
  5610. echoContent red "=============================================================="
  5611. read -r -p "请选择:" selectAccessLogType
  5612. local configPathLog=${configPath//conf\//}
  5613. case ${selectAccessLogType} in
  5614. 1)
  5615. if [[ "${logStatus}" == "false" ]]; then
  5616. realityLogShow=true
  5617. cat <<EOF >${configPath}00_log.json
  5618. {
  5619. "log": {
  5620. "access":"${configPathLog}access.log",
  5621. "error": "${configPathLog}error.log",
  5622. "loglevel": "debug"
  5623. }
  5624. }
  5625. EOF
  5626. elif [[ "${logStatus}" == "true" ]]; then
  5627. realityLogShow=false
  5628. cat <<EOF >${configPath}00_log.json
  5629. {
  5630. "log": {
  5631. "error": "${configPathLog}error.log",
  5632. "loglevel": "warning"
  5633. }
  5634. }
  5635. EOF
  5636. fi
  5637. if [[ -n ${realityStatus} ]]; then
  5638. local vlessVisionRealityInbounds
  5639. vlessVisionRealityInbounds=$(jq -r ".inbounds[0].streamSettings.realitySettings.show=${realityLogShow}" ${configPath}07_VLESS_vision_reality_inbounds.json)
  5640. echo "${vlessVisionRealityInbounds}" | jq . >${configPath}07_VLESS_vision_reality_inbounds.json
  5641. fi
  5642. reloadCore
  5643. checkLog 1
  5644. ;;
  5645. 2)
  5646. tail -f ${configPathLog}access.log
  5647. ;;
  5648. 3)
  5649. tail -f ${configPathLog}error.log
  5650. ;;
  5651. 4)
  5652. if [[ ! -f "/etc/v2ray-agent/crontab_tls.log" ]]; then
  5653. touch /etc/v2ray-agent/crontab_tls.log
  5654. fi
  5655. tail -n 100 /etc/v2ray-agent/crontab_tls.log
  5656. ;;
  5657. 5)
  5658. tail -n 100 /etc/v2ray-agent/tls/acme.log
  5659. ;;
  5660. 6)
  5661. echo >${configPathLog}access.log
  5662. echo >${configPathLog}error.log
  5663. ;;
  5664. esac
  5665. }
  5666. # 脚本快捷方式
  5667. aliasInstall() {
  5668. if [[ -f "$HOME/install.sh" ]] && [[ -d "/etc/v2ray-agent" ]] && grep <"$HOME/install.sh" -q "作者:mack-a"; then
  5669. mv "$HOME/install.sh" /etc/v2ray-agent/install.sh
  5670. local vasmaType=
  5671. if [[ -d "/usr/bin/" ]]; then
  5672. if [[ ! -f "/usr/bin/vasma" ]]; then
  5673. ln -s /etc/v2ray-agent/install.sh /usr/bin/vasma
  5674. chmod 700 /usr/bin/vasma
  5675. vasmaType=true
  5676. fi
  5677. rm -rf "$HOME/install.sh"
  5678. elif [[ -d "/usr/sbin" ]]; then
  5679. if [[ ! -f "/usr/sbin/vasma" ]]; then
  5680. ln -s /etc/v2ray-agent/install.sh /usr/sbin/vasma
  5681. chmod 700 /usr/sbin/vasma
  5682. vasmaType=true
  5683. fi
  5684. rm -rf "$HOME/install.sh"
  5685. fi
  5686. if [[ "${vasmaType}" == "true" ]]; then
  5687. echoContent green "快捷方式创建成功,可执行[vasma]重新打开脚本"
  5688. fi
  5689. fi
  5690. }
  5691. # 检查ipv6、ipv4
  5692. checkIPv6() {
  5693. currentIPv6IP=$(curl -s -6 -m 4 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2)
  5694. if [[ -z "${currentIPv6IP}" ]]; then
  5695. echoContent red " ---> 不支持ipv6"
  5696. exit 0
  5697. fi
  5698. }
  5699. # ipv6 分流
  5700. ipv6Routing() {
  5701. if [[ -z "${configPath}" ]]; then
  5702. echoContent red " ---> 未安装,请使用脚本安装"
  5703. menu
  5704. exit 0
  5705. fi
  5706. checkIPv6
  5707. echoContent skyBlue "\n功能 1/${totalProgress} : IPv6分流"
  5708. echoContent red "\n=============================================================="
  5709. echoContent yellow "1.查看已分流域名"
  5710. echoContent yellow "2.添加域名"
  5711. echoContent yellow "3.设置IPv6全局"
  5712. echoContent yellow "4.卸载IPv6分流"
  5713. echoContent red "=============================================================="
  5714. read -r -p "请选择:" ipv6Status
  5715. if [[ "${ipv6Status}" == "1" ]]; then
  5716. showIPv6Routing
  5717. exit 0
  5718. elif [[ "${ipv6Status}" == "2" ]]; then
  5719. echoContent red "=============================================================="
  5720. echoContent yellow "# 注意事项\n"
  5721. echoContent yellow "# 注意事项"
  5722. echoContent yellow "# 使用教程:https://www.v2ray-agent.com/archives/1683226921000 \n"
  5723. read -r -p "请按照上面示例录入域名:" domainList
  5724. if [[ "${coreInstallType}" == "1" ]]; then
  5725. addInstallRouting IPv6_out outboundTag "${domainList}"
  5726. addXrayOutbound IPv6_out
  5727. fi
  5728. if [[ -n "${singBoxConfigPath}" ]]; then
  5729. addSingBoxRouteRule "IPv6_out" "${domainList}" "IPv6_route"
  5730. addSingBoxOutbound 01_direct_outbound
  5731. addSingBoxOutbound IPv6_out
  5732. addSingBoxOutbound IPv4_out
  5733. fi
  5734. echoContent green " ---> 添加完毕"
  5735. elif [[ "${ipv6Status}" == "3" ]]; then
  5736. echoContent red "=============================================================="
  5737. echoContent yellow "# 注意事项\n"
  5738. echoContent yellow "1.会删除所有设置的分流规则"
  5739. echoContent yellow "2.会删除IPv6之外的所有出站规则\n"
  5740. read -r -p "是否确认设置?[y/n]:" IPv6OutStatus
  5741. if [[ "${IPv6OutStatus}" == "y" ]]; then
  5742. if [[ "${coreInstallType}" == "1" ]]; then
  5743. addXrayOutbound IPv6_out
  5744. removeXrayOutbound IPv4_out
  5745. removeXrayOutbound z_direct_outbound
  5746. removeXrayOutbound blackhole_out
  5747. removeXrayOutbound wireguard_out_IPv4
  5748. removeXrayOutbound wireguard_out_IPv6
  5749. removeXrayOutbound socks5_outbound
  5750. rm ${configPath}09_routing.json >/dev/null 2>&1
  5751. fi
  5752. if [[ -n "${singBoxConfigPath}" ]]; then
  5753. removeSingBoxConfig IPv4_out
  5754. removeSingBoxConfig wireguard_endpoints_IPv4_route
  5755. removeSingBoxConfig wireguard_endpoints_IPv6_route
  5756. removeSingBoxConfig wireguard_endpoints_IPv4
  5757. removeSingBoxConfig wireguard_endpoints_IPv6
  5758. removeSingBoxConfig socks5_inbound_route
  5759. removeSingBoxConfig IPv6_route
  5760. removeSingBoxConfig 01_direct_outbound
  5761. addSingBoxOutbound IPv6_out
  5762. fi
  5763. echoContent green " ---> IPv6全局出站设置完毕"
  5764. else
  5765. echoContent green " ---> 放弃设置"
  5766. exit 0
  5767. fi
  5768. elif [[ "${ipv6Status}" == "4" ]]; then
  5769. if [[ "${coreInstallType}" == "1" ]]; then
  5770. unInstallRouting IPv6_out outboundTag
  5771. removeXrayOutbound IPv6_out
  5772. addXrayOutbound "z_direct_outbound"
  5773. fi
  5774. if [[ -n "${singBoxConfigPath}" ]]; then
  5775. removeSingBoxConfig IPv6_out
  5776. removeSingBoxConfig "IPv6_route"
  5777. addSingBoxOutbound "01_direct_outbound"
  5778. fi
  5779. echoContent green " ---> IPv6分流卸载成功"
  5780. else
  5781. echoContent red " ---> 选择错误"
  5782. exit 0
  5783. fi
  5784. reloadCore
  5785. }
  5786. # ipv6分流规则展示
  5787. showIPv6Routing() {
  5788. if [[ "${coreInstallType}" == "1" ]]; then
  5789. if [[ -f "${configPath}09_routing.json" ]]; then
  5790. echoContent yellow "Xray-core:"
  5791. jq -r -c '.routing.rules[]|select (.outboundTag=="IPv6_out")|.domain' ${configPath}09_routing.json | jq -r
  5792. elif [[ ! -f "${configPath}09_routing.json" && -f "${configPath}IPv6_out.json" ]]; then
  5793. echoContent yellow "Xray-core"
  5794. echoContent green " ---> 已设置IPv6全局分流"
  5795. else
  5796. echoContent yellow " ---> 未安装IPv6分流"
  5797. fi
  5798. fi
  5799. if [[ -n "${singBoxConfigPath}" ]]; then
  5800. if [[ -f "${singBoxConfigPath}IPv6_route.json" ]]; then
  5801. echoContent yellow "sing-box"
  5802. jq -r -c '.route.rules[]|select (.outbound=="IPv6_out")' "${singBoxConfigPath}IPv6_route.json" | jq -r
  5803. elif [[ ! -f "${singBoxConfigPath}IPv6_route.json" && -f "${singBoxConfigPath}IPv6_out.json" ]]; then
  5804. echoContent yellow "sing-box"
  5805. echoContent green " ---> 已设置IPv6全局分流"
  5806. else
  5807. echoContent yellow " ---> 未安装IPv6分流"
  5808. fi
  5809. fi
  5810. }
  5811. # bt下载管理
  5812. btTools() {
  5813. if [[ "${coreInstallType}" == "2" ]]; then
  5814. echoContent red "\n ---> 此功能仅支持Xray-core内核,请等待后续更新"
  5815. exit 0
  5816. fi
  5817. if [[ -z "${configPath}" ]]; then
  5818. echoContent red " ---> 未安装,请使用脚本安装"
  5819. menu
  5820. exit 0
  5821. fi
  5822. echoContent skyBlue "\n功能 1/${totalProgress} : bt下载管理"
  5823. echoContent red "\n=============================================================="
  5824. if [[ -f ${configPath}09_routing.json ]] && grep -q bittorrent <${configPath}09_routing.json; then
  5825. echoContent yellow "当前状态:已禁止下载BT"
  5826. else
  5827. echoContent yellow "当前状态:允许下载BT"
  5828. fi
  5829. echoContent yellow "1.禁止下载BT"
  5830. echoContent yellow "2.允许下载BT"
  5831. echoContent red "=============================================================="
  5832. read -r -p "请选择:" btStatus
  5833. if [[ "${btStatus}" == "1" ]]; then
  5834. if [[ -f "${configPath}09_routing.json" ]]; then
  5835. unInstallRouting blackhole_out outboundTag bittorrent
  5836. routing=$(jq -r '.routing.rules += [{"type":"field","outboundTag":"blackhole_out","protocol":["bittorrent"]}]' ${configPath}09_routing.json)
  5837. echo "${routing}" | jq . >${configPath}09_routing.json
  5838. else
  5839. cat <<EOF >${configPath}09_routing.json
  5840. {
  5841. "routing":{
  5842. "domainStrategy": "IPOnDemand",
  5843. "rules": [
  5844. {
  5845. "type": "field",
  5846. "outboundTag": "blackhole_out",
  5847. "protocol": [ "bittorrent" ]
  5848. }
  5849. ]
  5850. }
  5851. }
  5852. EOF
  5853. fi
  5854. installSniffing
  5855. removeXrayOutbound blackhole_out
  5856. addXrayOutbound blackhole_out
  5857. echoContent green " ---> 禁止BT下载"
  5858. elif [[ "${btStatus}" == "2" ]]; then
  5859. unInstallSniffing
  5860. unInstallRouting blackhole_out outboundTag bittorrent
  5861. echoContent green " ---> 允许BT下载"
  5862. else
  5863. echoContent red " ---> 选择错误"
  5864. exit 0
  5865. fi
  5866. reloadCore
  5867. }
  5868. # 域名黑名单
  5869. blacklist() {
  5870. if [[ -z "${configPath}" ]]; then
  5871. echoContent red " ---> 未安装,请使用脚本安装"
  5872. menu
  5873. exit 0
  5874. fi
  5875. echoContent skyBlue "\n进度 $1/${totalProgress} : 域名黑名单"
  5876. echoContent red "\n=============================================================="
  5877. echoContent yellow "1.查看已屏蔽域名"
  5878. echoContent yellow "2.添加域名"
  5879. echoContent yellow "3.屏蔽大陆域名"
  5880. echoContent yellow "4.卸载黑名单"
  5881. echoContent red "=============================================================="
  5882. read -r -p "请选择:" blacklistStatus
  5883. if [[ "${blacklistStatus}" == "1" ]]; then
  5884. jq -r -c '.routing.rules[]|select (.outboundTag=="blackhole_out")|.domain' ${configPath}09_routing.json | jq -r
  5885. exit 0
  5886. elif [[ "${blacklistStatus}" == "2" ]]; then
  5887. echoContent red "=============================================================="
  5888. echoContent yellow "# 注意事项\n"
  5889. echoContent yellow "1.规则支持预定义域名列表[https://github.com/v2fly/domain-list-community]"
  5890. echoContent yellow "2.规则支持自定义域名"
  5891. echoContent yellow "3.录入示例:speedtest,facebook,cn,example.com"
  5892. echoContent yellow "4.如果域名在预定义域名列表中存在则使用 geosite:xx,如果不存在则默认使用输入的域名"
  5893. echoContent yellow "5.添加规则为增量配置,不会删除之前设置的内容\n"
  5894. read -r -p "请按照上面示例录入域名:" domainList
  5895. if [[ "${coreInstallType}" == "1" ]]; then
  5896. addInstallRouting blackhole_out outboundTag "${domainList}"
  5897. addXrayOutbound blackhole_out
  5898. fi
  5899. if [[ -n "${singBoxConfigPath}" ]]; then
  5900. addSingBoxRouteRule "block_domain_outbound" "${domainList}" "block_domain_route"
  5901. addSingBoxOutbound "block_domain_outbound"
  5902. addSingBoxOutbound "01_direct_outbound"
  5903. fi
  5904. echoContent green " ---> 添加完毕"
  5905. elif [[ "${blacklistStatus}" == "3" ]]; then
  5906. if [[ "${coreInstallType}" == "1" ]]; then
  5907. unInstallRouting blackhole_out outboundTag
  5908. addInstallRouting blackhole_out outboundTag "cn"
  5909. addXrayOutbound blackhole_out
  5910. fi
  5911. if [[ -n "${singBoxConfigPath}" ]]; then
  5912. addSingBoxRouteRule "cn_block_outbound" "cn" "cn_block_route"
  5913. addSingBoxRouteRule "01_direct_outbound" "googleapis.com,googleapis.cn,xn--ngstr-lra8j.com,gstatic.com" "cn_01_google_play_route"
  5914. addSingBoxOutbound "cn_block_outbound"
  5915. addSingBoxOutbound "01_direct_outbound"
  5916. fi
  5917. echoContent green " ---> 屏蔽大陆域名完毕"
  5918. elif [[ "${blacklistStatus}" == "4" ]]; then
  5919. if [[ "${coreInstallType}" == "1" ]]; then
  5920. unInstallRouting blackhole_out outboundTag
  5921. fi
  5922. if [[ -n "${singBoxConfigPath}" ]]; then
  5923. removeSingBoxConfig "cn_block_route"
  5924. removeSingBoxConfig "cn_block_outbound"
  5925. removeSingBoxConfig "cn_01_google_play_route"
  5926. removeSingBoxConfig "block_domain_route"
  5927. removeSingBoxConfig "block_domain_outbound"
  5928. fi
  5929. echoContent green " ---> 域名黑名单删除完毕"
  5930. else
  5931. echoContent red " ---> 选择错误"
  5932. exit 0
  5933. fi
  5934. reloadCore
  5935. }
  5936. # 添加routing配置
  5937. addInstallRouting() {
  5938. local tag=$1 # warp-socks
  5939. local type=$2 # outboundTag/inboundTag
  5940. local domain=$3 # 域名
  5941. if [[ -z "${tag}" || -z "${type}" || -z "${domain}" ]]; then
  5942. echoContent red " ---> 参数错误"
  5943. exit 0
  5944. fi
  5945. local routingRule=
  5946. if [[ ! -f "${configPath}09_routing.json" ]]; then
  5947. cat <<EOF >${configPath}09_routing.json
  5948. {
  5949. "routing":{
  5950. "type": "field",
  5951. "rules": [
  5952. {
  5953. "type": "field",
  5954. "domain": [
  5955. ],
  5956. "outboundTag": "${tag}"
  5957. }
  5958. ]
  5959. }
  5960. }
  5961. EOF
  5962. fi
  5963. local routingRule=
  5964. routingRule=$(jq -r ".routing.rules[]|select(.outboundTag==\"${tag}\" and (.protocol == null))" ${configPath}09_routing.json)
  5965. if [[ -z "${routingRule}" ]]; then
  5966. routingRule="{\"type\": \"field\",\"domain\": [],\"outboundTag\": \"${tag}\"}"
  5967. fi
  5968. while read -r line; do
  5969. if echo "${routingRule}" | grep -q "${line}"; then
  5970. echoContent yellow " ---> ${line}已存在,跳过"
  5971. else
  5972. local geositeStatus
  5973. geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message)
  5974. if [[ "${geositeStatus}" == "null" ]]; then
  5975. routingRule=$(echo "${routingRule}" | jq -r '.domain += ["geosite:'"${line}"'"]')
  5976. else
  5977. routingRule=$(echo "${routingRule}" | jq -r '.domain += ["domain:'"${line}"'"]')
  5978. fi
  5979. fi
  5980. done < <(echo "${domain}" | tr ',' '\n')
  5981. unInstallRouting "${tag}" "${type}"
  5982. if ! grep -q "gstatic.com" ${configPath}09_routing.json && [[ "${tag}" == "blackhole_out" ]]; then
  5983. local routing=
  5984. routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": [\"gstatic.com\"],\"outboundTag\": \"direct\"}]" ${configPath}09_routing.json)
  5985. echo "${routing}" | jq . >${configPath}09_routing.json
  5986. fi
  5987. routing=$(jq -r ".routing.rules += [${routingRule}]" ${configPath}09_routing.json)
  5988. echo "${routing}" | jq . >${configPath}09_routing.json
  5989. }
  5990. # 根据tag卸载Routing
  5991. unInstallRouting() {
  5992. local tag=$1
  5993. local type=$2
  5994. local protocol=$3
  5995. if [[ -f "${configPath}09_routing.json" ]]; then
  5996. local routing=
  5997. if [[ -n "${protocol}" ]]; then
  5998. routing=$(jq -r "del(.routing.rules[] | select(.${type} == \"${tag}\" and (.protocol | index(\"${protocol}\"))))" ${configPath}09_routing.json)
  5999. echo "${routing}" | jq . >${configPath}09_routing.json
  6000. else
  6001. routing=$(jq -r "del(.routing.rules[] | select(.${type} == \"${tag}\" and (.protocol == null )))" ${configPath}09_routing.json)
  6002. echo "${routing}" | jq . >${configPath}09_routing.json
  6003. fi
  6004. fi
  6005. }
  6006. # 卸载嗅探
  6007. unInstallSniffing() {
  6008. find ${configPath} -name "*inbounds.json*" | awk -F "[c][o][n][f][/]" '{print $2}' | while read -r inbound; do
  6009. if grep -q "destOverride" <"${configPath}${inbound}"; then
  6010. sniffing=$(jq -r 'del(.inbounds[0].sniffing)' "${configPath}${inbound}")
  6011. echo "${sniffing}" | jq . >"${configPath}${inbound}"
  6012. fi
  6013. done
  6014. }
  6015. # 安装嗅探
  6016. installSniffing() {
  6017. readInstallType
  6018. if [[ "${coreInstallType}" == "1" ]]; then
  6019. if [[ -f "${configPath}02_VLESS_TCP_inbounds.json" ]]; then
  6020. if ! grep -q "destOverride" <"${configPath}02_VLESS_TCP_inbounds.json"; then
  6021. sniffing=$(jq -r '.inbounds[0].sniffing = {"enabled":true,"destOverride":["http","tls","quic"]}' "${configPath}02_VLESS_TCP_inbounds.json")
  6022. echo "${sniffing}" | jq . >"${configPath}02_VLESS_TCP_inbounds.json"
  6023. fi
  6024. fi
  6025. fi
  6026. }
  6027. # 读取第三方warp配置
  6028. readConfigWarpReg() {
  6029. if [[ ! -f "/etc/v2ray-agent/warp/config" ]]; then
  6030. /etc/v2ray-agent/warp/warp-reg >/etc/v2ray-agent/warp/config
  6031. fi
  6032. secretKeyWarpReg=$(grep <"/etc/v2ray-agent/warp/config" private_key | awk '{print $2}')
  6033. addressWarpReg=$(grep <"/etc/v2ray-agent/warp/config" v6 | awk '{print $2}')
  6034. publicKeyWarpReg=$(grep <"/etc/v2ray-agent/warp/config" public_key | awk '{print $2}')
  6035. reservedWarpReg=$(grep <"/etc/v2ray-agent/warp/config" reserved | awk -F "[:]" '{print $2}')
  6036. }
  6037. # 安装warp-reg工具
  6038. installWarpReg() {
  6039. if [[ ! -f "/etc/v2ray-agent/warp/warp-reg" ]]; then
  6040. echo
  6041. echoContent yellow "# 注意事项"
  6042. echoContent yellow "# 依赖第三方程序,请熟知其中风险"
  6043. echoContent yellow "# 项目地址:https://github.com/badafans/warp-reg \n"
  6044. read -r -p "warp-reg未安装,是否安装 ?[y/n]:" installWarpRegStatus
  6045. if [[ "${installWarpRegStatus}" == "y" ]]; then
  6046. curl -sLo /etc/v2ray-agent/warp/warp-reg "https://github.com/badafans/warp-reg/releases/download/v1.0/${warpRegCoreCPUVendor}"
  6047. chmod 655 /etc/v2ray-agent/warp/warp-reg
  6048. else
  6049. echoContent yellow " ---> 放弃安装"
  6050. exit 0
  6051. fi
  6052. fi
  6053. }
  6054. # 展示warp分流域名
  6055. showWireGuardDomain() {
  6056. local type=$1
  6057. # xray
  6058. if [[ "${coreInstallType}" == "1" ]]; then
  6059. if [[ -f "${configPath}09_routing.json" ]]; then
  6060. echoContent yellow "Xray-core"
  6061. jq -r -c '.routing.rules[]|select (.outboundTag=="wireguard_out_'"${type}"'")|.domain' ${configPath}09_routing.json | jq -r
  6062. elif [[ ! -f "${configPath}09_routing.json" && -f "${configPath}wireguard_out_${type}.json" ]]; then
  6063. echoContent yellow "Xray-core"
  6064. echoContent green " ---> 已设置warp ${type}全局分流"
  6065. else
  6066. echoContent yellow " ---> 未安装warp ${type}分流"
  6067. fi
  6068. fi
  6069. # sing-box
  6070. if [[ -n "${singBoxConfigPath}" ]]; then
  6071. if [[ -f "${singBoxConfigPath}wireguard_endpoints_${type}_route.json" ]]; then
  6072. echoContent yellow "sing-box"
  6073. jq -r -c '.route.rules[]' "${singBoxConfigPath}wireguard_endpoints_${type}_route.json" | jq -r
  6074. elif [[ ! -f "${singBoxConfigPath}wireguard_endpoints_${type}_route.json" && -f "${singBoxConfigPath}wireguard_endpoints_${type}.json" ]]; then
  6075. echoContent yellow "sing-box"
  6076. echoContent green " ---> 已设置warp ${type}全局分流"
  6077. else
  6078. echoContent yellow " ---> 未安装warp ${type}分流"
  6079. fi
  6080. fi
  6081. }
  6082. # 添加WireGuard分流
  6083. addWireGuardRoute() {
  6084. local type=$1
  6085. local tag=$2
  6086. local domainList=$3
  6087. # xray
  6088. if [[ "${coreInstallType}" == "1" ]]; then
  6089. addInstallRouting "wireguard_out_${type}" "${tag}" "${domainList}"
  6090. addXrayOutbound "wireguard_out_${type}"
  6091. fi
  6092. # sing-box
  6093. if [[ -n "${singBoxConfigPath}" ]]; then
  6094. # rule
  6095. addSingBoxRouteRule "wireguard_endpoints_${type}" "${domainList}" "wireguard_endpoints_${type}_route"
  6096. # addSingBoxOutbound "wireguard_out_${type}" "wireguard_out"
  6097. if [[ -n "${domainList}" ]]; then
  6098. addSingBoxOutbound "01_direct_outbound"
  6099. fi
  6100. # outbound
  6101. addSingBoxWireGuardEndpoints "${type}"
  6102. fi
  6103. }
  6104. # 卸载wireGuard
  6105. unInstallWireGuard() {
  6106. local type=$1
  6107. if [[ "${coreInstallType}" == "1" ]]; then
  6108. if [[ "${type}" == "IPv4" ]]; then
  6109. if [[ ! -f "${configPath}wireguard_out_IPv6.json" ]]; then
  6110. rm -rf /etc/v2ray-agent/warp/config >/dev/null 2>&1
  6111. fi
  6112. elif [[ "${type}" == "IPv6" ]]; then
  6113. if [[ ! -f "${configPath}wireguard_out_IPv4.json" ]]; then
  6114. rm -rf /etc/v2ray-agent/warp/config >/dev/null 2>&1
  6115. fi
  6116. fi
  6117. fi
  6118. if [[ -n "${singBoxConfigPath}" ]]; then
  6119. if [[ ! -f "${singBoxConfigPath}wireguard_endpoints_IPv6_route.json" && ! -f "${singBoxConfigPath}wireguard_endpoints_IPv4_route.json" ]]; then
  6120. rm "${singBoxConfigPath}wireguard_outbound.json" >/dev/null 2>&1
  6121. rm -rf /etc/v2ray-agent/warp/config >/dev/null 2>&1
  6122. fi
  6123. fi
  6124. }
  6125. # 移除WireGuard分流
  6126. removeWireGuardRoute() {
  6127. local type=$1
  6128. if [[ "${coreInstallType}" == "1" ]]; then
  6129. unInstallRouting wireguard_out_"${type}" outboundTag
  6130. removeXrayOutbound "wireguard_out_${type}"
  6131. if [[ ! -f "${configPath}IPv4_out.json" ]]; then
  6132. addXrayOutbound IPv4_out
  6133. fi
  6134. fi
  6135. # sing-box
  6136. if [[ -n "${singBoxConfigPath}" ]]; then
  6137. removeSingBoxRouteRule "wireguard_endpoints_${type}"
  6138. fi
  6139. unInstallWireGuard "${type}"
  6140. }
  6141. # warp分流-第三方IPv4
  6142. warpRoutingReg() {
  6143. local type=$2
  6144. echoContent skyBlue "\n进度 $1/${totalProgress} : WARP分流[第三方]"
  6145. echoContent red "=============================================================="
  6146. echoContent yellow "1.查看已分流域名"
  6147. echoContent yellow "2.添加域名"
  6148. echoContent yellow "3.设置WARP全局"
  6149. echoContent yellow "4.卸载WARP分流"
  6150. echoContent red "=============================================================="
  6151. read -r -p "请选择:" warpStatus
  6152. installWarpReg
  6153. readConfigWarpReg
  6154. local address=
  6155. if [[ ${type} == "IPv4" ]]; then
  6156. address="172.16.0.2/32"
  6157. elif [[ ${type} == "IPv6" ]]; then
  6158. address="${addressWarpReg}/128"
  6159. else
  6160. echoContent red " ---> IP获取失败,退出安装"
  6161. fi
  6162. if [[ "${warpStatus}" == "1" ]]; then
  6163. showWireGuardDomain "${type}"
  6164. exit 0
  6165. elif [[ "${warpStatus}" == "2" ]]; then
  6166. echoContent yellow "# 注意事项"
  6167. echoContent yellow "# 支持sing-box、Xray-core"
  6168. echoContent yellow "# 使用教程:https://www.v2ray-agent.com/archives/1683226921000 \n"
  6169. read -r -p "请按照上面示例录入域名:" domainList
  6170. addWireGuardRoute "${type}" outboundTag "${domainList}"
  6171. echoContent green " ---> 添加完毕"
  6172. elif [[ "${warpStatus}" == "3" ]]; then
  6173. echoContent red "=============================================================="
  6174. echoContent yellow "# 注意事项\n"
  6175. echoContent yellow "1.会删除所有设置的分流规则"
  6176. echoContent yellow "2.会删除除WARP[第三方]之外的所有出站规则\n"
  6177. read -r -p "是否确认设置?[y/n]:" warpOutStatus
  6178. if [[ "${warpOutStatus}" == "y" ]]; then
  6179. readConfigWarpReg
  6180. if [[ "${coreInstallType}" == "1" ]]; then
  6181. addXrayOutbound "wireguard_out_${type}"
  6182. if [[ "${type}" == "IPv4" ]]; then
  6183. removeXrayOutbound "wireguard_out_IPv6"
  6184. elif [[ "${type}" == "IPv6" ]]; then
  6185. removeXrayOutbound "wireguard_out_IPv4"
  6186. fi
  6187. removeXrayOutbound IPv4_out
  6188. removeXrayOutbound IPv6_out
  6189. removeXrayOutbound z_direct_outbound
  6190. removeXrayOutbound blackhole_out
  6191. removeXrayOutbound socks5_outbound
  6192. rm ${configPath}09_routing.json >/dev/null 2>&1
  6193. fi
  6194. if [[ -n "${singBoxConfigPath}" ]]; then
  6195. removeSingBoxConfig IPv4_out
  6196. removeSingBoxConfig IPv6_out
  6197. removeSingBoxConfig 01_direct_outbound
  6198. # 删除所有分流规则
  6199. removeSingBoxConfig wireguard_endpoints_IPv4_route
  6200. removeSingBoxConfig wireguard_endpoints_IPv6_route
  6201. removeSingBoxConfig IPv6_route
  6202. removeSingBoxConfig socks5_inbound_route
  6203. addSingBoxWireGuardEndpoints "${type}"
  6204. addWireGuardRoute "${type}" outboundTag ""
  6205. if [[ "${type}" == "IPv4" ]]; then
  6206. removeSingBoxConfig wireguard_endpoints_IPv6
  6207. else
  6208. removeSingBoxConfig wireguard_endpoints_IPv4
  6209. fi
  6210. # outbound
  6211. # addSingBoxOutbound "wireguard_out_${type}" "wireguard_out"
  6212. fi
  6213. echoContent green " ---> WARP全局出站设置完毕"
  6214. else
  6215. echoContent green " ---> 放弃设置"
  6216. exit 0
  6217. fi
  6218. elif [[ "${warpStatus}" == "4" ]]; then
  6219. if [[ "${coreInstallType}" == "1" ]]; then
  6220. unInstallRouting "wireguard_out_${type}" outboundTag
  6221. removeXrayOutbound "wireguard_out_${type}"
  6222. addXrayOutbound "z_direct_outbound"
  6223. fi
  6224. if [[ -n "${singBoxConfigPath}" ]]; then
  6225. removeSingBoxConfig "wireguard_endpoints_${type}_route"
  6226. removeSingBoxConfig "wireguard_endpoints_${type}"
  6227. addSingBoxOutbound "01_direct_outbound"
  6228. fi
  6229. echoContent green " ---> 卸载WARP ${type}分流完毕"
  6230. else
  6231. echoContent red " ---> 选择错误"
  6232. exit 0
  6233. fi
  6234. reloadCore
  6235. }
  6236. # 分流工具
  6237. routingToolsMenu() {
  6238. echoContent skyBlue "\n功能 1/${totalProgress} : 分流工具"
  6239. echoContent red "\n=============================================================="
  6240. echoContent yellow "# 注意事项"
  6241. echoContent yellow "# 用于服务端的流量分流,可用于解锁ChatGPT、流媒体等相关内容\n"
  6242. echoContent yellow "1.WARP分流【第三方 IPv4】"
  6243. echoContent yellow "2.WARP分流【第三方 IPv6】"
  6244. echoContent yellow "3.IPv6分流"
  6245. echoContent yellow "4.Socks5分流【替换任意门分流】"
  6246. echoContent yellow "5.DNS分流"
  6247. # echoContent yellow "6.VMess+WS+TLS分流"
  6248. echoContent yellow "7.SNI反向代理分流"
  6249. read -r -p "请选择:" selectType
  6250. case ${selectType} in
  6251. 1)
  6252. warpRoutingReg 1 IPv4
  6253. ;;
  6254. 2)
  6255. warpRoutingReg 1 IPv6
  6256. ;;
  6257. 3)
  6258. ipv6Routing 1
  6259. ;;
  6260. 4)
  6261. socks5Routing
  6262. ;;
  6263. 5)
  6264. dnsRouting 1
  6265. ;;
  6266. # 6)
  6267. # if [[ -n "${singBoxConfigPath}" ]]; then
  6268. # echoContent red "\n ---> 此功能不支持Hysteria2、Tuic"
  6269. # fi
  6270. # vmessWSRouting 1
  6271. # ;;
  6272. 7)
  6273. if [[ -n "${singBoxConfigPath}" ]]; then
  6274. echoContent red "\n ---> 此功能不支持Hysteria2、Tuic"
  6275. fi
  6276. sniRouting 1
  6277. ;;
  6278. esac
  6279. }
  6280. # VMess+WS+TLS 分流
  6281. vmessWSRouting() {
  6282. echoContent skyBlue "\n功能 1/${totalProgress} : VMess+WS+TLS 分流"
  6283. echoContent red "\n=============================================================="
  6284. echoContent yellow "# 注意事项"
  6285. echoContent yellow "# 使用教程:https://www.v2ray-agent.com/archives/1683226921000 \n"
  6286. echoContent yellow "1.添加出站"
  6287. echoContent yellow "2.卸载"
  6288. read -r -p "请选择:" selectType
  6289. case ${selectType} in
  6290. 1)
  6291. setVMessWSRoutingOutbounds
  6292. ;;
  6293. 2)
  6294. removeVMessWSRouting
  6295. ;;
  6296. esac
  6297. }
  6298. # Socks5分流
  6299. socks5Routing() {
  6300. if [[ -z "${coreInstallType}" ]]; then
  6301. echoContent red " ---> 未安装任意协议,请使用 1.安装 或者 2.任意组合安装 进行安装后使用"
  6302. exit 0
  6303. fi
  6304. echoContent skyBlue "\n功能 1/${totalProgress} : Socks5分流"
  6305. echoContent red "\n=============================================================="
  6306. echoContent red "# 注意事项"
  6307. echoContent yellow "# 流量明文访问"
  6308. echoContent yellow "# 仅限正常网络环境下设备间流量转发,禁止用于代理访问。"
  6309. echoContent yellow "# 使用教程:https://www.v2ray-agent.com/archives/1683226921000#heading-5 \n"
  6310. echoContent yellow "1.Socks5出站"
  6311. echoContent yellow "2.Socks5入站"
  6312. echoContent yellow "3.卸载"
  6313. read -r -p "请选择:" selectType
  6314. case ${selectType} in
  6315. 1)
  6316. socks5OutboundRoutingMenu
  6317. ;;
  6318. 2)
  6319. socks5InboundRoutingMenu
  6320. ;;
  6321. 3)
  6322. removeSocks5Routing
  6323. ;;
  6324. esac
  6325. }
  6326. # Socks5入站菜单
  6327. socks5InboundRoutingMenu() {
  6328. readInstallType
  6329. echoContent skyBlue "\n功能 1/1 : Socks5入站"
  6330. echoContent red "\n=============================================================="
  6331. echoContent yellow "1.安装Socks5入站"
  6332. echoContent yellow "2.查看分流规则"
  6333. echoContent yellow "3.添加分流规则"
  6334. echoContent yellow "4.查看入站配置"
  6335. read -r -p "请选择:" selectType
  6336. case ${selectType} in
  6337. 1)
  6338. totalProgress=1
  6339. installSingBox 1
  6340. installSingBoxService 1
  6341. setSocks5Inbound
  6342. setSocks5InboundRouting
  6343. reloadCore
  6344. socks5InboundRoutingMenu
  6345. ;;
  6346. 2)
  6347. showSingBoxRoutingRules socks5_inbound_route
  6348. socks5InboundRoutingMenu
  6349. ;;
  6350. 3)
  6351. setSocks5InboundRouting addRules
  6352. reloadCore
  6353. socks5InboundRoutingMenu
  6354. ;;
  6355. 4)
  6356. if [[ -f "${singBoxConfigPath}20_socks5_inbounds.json" ]]; then
  6357. echoContent yellow "\n ---> 下列内容需要配置到其他机器的出站,请不要进行代理行为\n"
  6358. echoContent green " 端口:$(jq .inbounds[0].listen_port ${singBoxConfigPath}20_socks5_inbounds.json)"
  6359. echoContent green " 用户名称:$(jq -r .inbounds[0].users[0].username ${singBoxConfigPath}20_socks5_inbounds.json)"
  6360. echoContent green " 用户密码:$(jq -r .inbounds[0].users[0].password ${singBoxConfigPath}20_socks5_inbounds.json)"
  6361. else
  6362. echoContent red " ---> 未安装相应功能"
  6363. socks5InboundRoutingMenu
  6364. fi
  6365. ;;
  6366. esac
  6367. }
  6368. # Socks5出站菜单
  6369. socks5OutboundRoutingMenu() {
  6370. echoContent skyBlue "\n功能 1/1 : Socks5出站"
  6371. echoContent red "\n=============================================================="
  6372. echoContent yellow "1.安装Socks5出站"
  6373. echoContent yellow "2.设置Socks5全局转发"
  6374. echoContent yellow "3.查看分流规则"
  6375. echoContent yellow "4.添加分流规则"
  6376. read -r -p "请选择:" selectType
  6377. case ${selectType} in
  6378. 1)
  6379. setSocks5Outbound
  6380. setSocks5OutboundRouting
  6381. reloadCore
  6382. socks5OutboundRoutingMenu
  6383. ;;
  6384. 2)
  6385. setSocks5Outbound
  6386. setSocks5OutboundRoutingAll
  6387. reloadCore
  6388. socks5OutboundRoutingMenu
  6389. ;;
  6390. 3)
  6391. showSingBoxRoutingRules socks5_outbound_route
  6392. showXrayRoutingRules socks5_outbound
  6393. socks5OutboundRoutingMenu
  6394. ;;
  6395. 4)
  6396. setSocks5OutboundRouting addRules
  6397. reloadCore
  6398. socks5OutboundRoutingMenu
  6399. ;;
  6400. esac
  6401. }
  6402. # socks5全局
  6403. setSocks5OutboundRoutingAll() {
  6404. echoContent red "=============================================================="
  6405. echoContent yellow "# 注意事项\n"
  6406. echoContent yellow "1.会删除所有已经设置的分流规则,包括其他分流(warp、IPv6等)"
  6407. echoContent yellow "2.会删除Socks5之外的所有出站规则\n"
  6408. read -r -p "是否确认设置?[y/n]:" socksOutStatus
  6409. if [[ "${socksOutStatus}" == "y" ]]; then
  6410. if [[ "${coreInstallType}" == "1" ]]; then
  6411. removeXrayOutbound IPv4_out
  6412. removeXrayOutbound IPv6_out
  6413. removeXrayOutbound z_direct_outbound
  6414. removeXrayOutbound blackhole_out
  6415. removeXrayOutbound wireguard_out_IPv4
  6416. removeXrayOutbound wireguard_out_IPv6
  6417. rm ${configPath}09_routing.json >/dev/null 2>&1
  6418. fi
  6419. if [[ -n "${singBoxConfigPath}" ]]; then
  6420. removeSingBoxConfig IPv4_out
  6421. removeSingBoxConfig IPv6_out
  6422. removeSingBoxConfig wireguard_endpoints_IPv4_route
  6423. removeSingBoxConfig wireguard_endpoints_IPv6_route
  6424. removeSingBoxConfig wireguard_endpoints_IPv4
  6425. removeSingBoxConfig wireguard_endpoints_IPv6
  6426. removeSingBoxConfig socks5_outbound_route
  6427. removeSingBoxConfig 01_direct_outbound
  6428. fi
  6429. echoContent green " ---> Socks5全局出站设置完毕"
  6430. fi
  6431. }
  6432. # socks5 分流规则
  6433. showSingBoxRoutingRules() {
  6434. if [[ -n "${singBoxConfigPath}" ]]; then
  6435. if [[ -f "${singBoxConfigPath}$1.json" ]]; then
  6436. jq .route.rules "${singBoxConfigPath}$1.json"
  6437. elif [[ "$1" == "socks5_outbound_route" && -f "${singBoxConfigPath}socks5_outbound.json" ]]; then
  6438. echoContent yellow "已安装 sing-box socks5全局出站分流"
  6439. echoContent yellow "\n出站分流配置:"
  6440. echoContent skyBlue "$(jq .outbounds[0] ${singBoxConfigPath}socks5_outbound.json)"
  6441. elif [[ "$1" == "socks5_inbound_route" && -f "${singBoxConfigPath}20_socks5_inbounds.json" ]]; then
  6442. echoContent yellow "已安装 sing-box socks5全局入站分流"
  6443. echoContent yellow "\n出站分流配置:"
  6444. echoContent skyBlue "$(jq .outbounds[0] ${singBoxConfigPath}socks5_outbound.json)"
  6445. fi
  6446. fi
  6447. }
  6448. # xray内核分流规则
  6449. showXrayRoutingRules() {
  6450. if [[ "${coreInstallType}" == "1" ]]; then
  6451. if [[ -f "${configPath}09_routing.json" ]]; then
  6452. jq ".routing.rules[]|select(.outboundTag==\"$1\")" "${configPath}09_routing.json"
  6453. echoContent yellow "\n已安装 xray-core socks5全局出站分流"
  6454. echoContent yellow "\n出站分流配置:"
  6455. echoContent skyBlue "$(jq .outbounds[0].settings.servers[0] ${configPath}socks5_outbound.json)"
  6456. elif [[ "$1" == "socks5_outbound" && -f "${configPath}socks5_outbound.json" ]]; then
  6457. echoContent yellow "\n已安装 xray-core socks5全局出站分流"
  6458. echoContent yellow "\n出站分流配置:"
  6459. echoContent skyBlue "$(jq .outbounds[0].settings.servers[0] ${configPath}socks5_outbound.json)"
  6460. fi
  6461. fi
  6462. }
  6463. # 卸载Socks5分流
  6464. removeSocks5Routing() {
  6465. echoContent skyBlue "\n功能 1/1 : 卸载Socks5分流"
  6466. echoContent red "\n=============================================================="
  6467. echoContent yellow "1.卸载Socks5出站"
  6468. echoContent yellow "2.卸载Socks5入站"
  6469. echoContent yellow "3.卸载全部"
  6470. read -r -p "请选择:" unInstallSocks5RoutingStatus
  6471. if [[ "${unInstallSocks5RoutingStatus}" == "1" ]]; then
  6472. if [[ "${coreInstallType}" == "1" ]]; then
  6473. removeXrayOutbound socks5_outbound
  6474. unInstallRouting socks5_outbound outboundTag
  6475. addXrayOutbound z_direct_outbound
  6476. fi
  6477. if [[ -n "${singBoxConfigPath}" ]]; then
  6478. removeSingBoxConfig socks5_outbound
  6479. removeSingBoxConfig socks5_outbound_route
  6480. addSingBoxOutbound 01_direct_outbound
  6481. fi
  6482. elif [[ "${unInstallSocks5RoutingStatus}" == "2" ]]; then
  6483. removeSingBoxConfig 20_socks5_inbounds
  6484. removeSingBoxConfig socks5_inbound_route
  6485. handleSingBox stop
  6486. elif [[ "${unInstallSocks5RoutingStatus}" == "3" ]]; then
  6487. if [[ "${coreInstallType}" == "1" ]]; then
  6488. removeXrayOutbound socks5_outbound
  6489. unInstallRouting socks5_outbound outboundTag
  6490. addXrayOutbound z_direct_outbound
  6491. fi
  6492. if [[ -n "${singBoxConfigPath}" ]]; then
  6493. removeSingBoxConfig socks5_outbound
  6494. removeSingBoxConfig socks5_outbound_route
  6495. removeSingBoxConfig 20_socks5_inbounds
  6496. removeSingBoxConfig socks5_inbound_route
  6497. addSingBoxOutbound 01_direct_outbound
  6498. fi
  6499. handleSingBox stop
  6500. else
  6501. echoContent red " ---> 选择错误"
  6502. exit 0
  6503. fi
  6504. echoContent green " ---> 卸载完毕"
  6505. reloadCore
  6506. }
  6507. # Socks5入站
  6508. setSocks5Inbound() {
  6509. echoContent yellow "\n==================== 配置 Socks5 入站(解锁机、落地机) =====================\n"
  6510. echoContent skyBlue "\n开始配置Socks5协议入站端口"
  6511. echo
  6512. mapfile -t result < <(initSingBoxPort "${singBoxSocks5Port}")
  6513. echoContent green "\n ---> 入站Socks5端口:${result[-1]}"
  6514. echoContent green "\n ---> 此端口需要配置到其他机器出站,请不要进行代理行为"
  6515. echoContent yellow "\n请输入自定义UUID[需合法],[回车]随机UUID"
  6516. read -r -p 'UUID:' socks5RoutingUUID
  6517. if [[ -z "${socks5RoutingUUID}" ]]; then
  6518. if [[ "${coreInstallType}" == "1" ]]; then
  6519. socks5RoutingUUID=$(/etc/v2ray-agent/xray/xray uuid)
  6520. elif [[ -n "${singBoxConfigPath}" ]]; then
  6521. socks5RoutingUUID=$(/etc/v2ray-agent/sing-box/sing-box generate uuid)
  6522. fi
  6523. fi
  6524. echo
  6525. echoContent green "用户名称:${socks5RoutingUUID}"
  6526. echoContent green "用户密码:${socks5RoutingUUID}"
  6527. echoContent yellow "\n请选择分流域名DNS解析类型"
  6528. echoContent yellow "# 注意事项:需要保证vps支持相应的DNS解析"
  6529. echoContent yellow "1.IPv4[回车默认]"
  6530. echoContent yellow "2.IPv6"
  6531. read -r -p 'IP类型:' socks5InboundDomainStrategyStatus
  6532. local domainStrategy=
  6533. if [[ -z "${socks5InboundDomainStrategyStatus}" || "${socks5InboundDomainStrategyStatus}" == "1" ]]; then
  6534. domainStrategy="ipv4_only"
  6535. elif [[ "${socks5InboundDomainStrategyStatus}" == "2" ]]; then
  6536. domainStrategy="ipv6_only"
  6537. else
  6538. echoContent red " ---> 选择类型错误"
  6539. exit 0
  6540. fi
  6541. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/20_socks5_inbounds.json
  6542. {
  6543. "inbounds":[
  6544. {
  6545. "type": "socks",
  6546. "listen":"::",
  6547. "listen_port":${result[-1]},
  6548. "tag":"socks5_inbound",
  6549. "users":[
  6550. {
  6551. "username": "${socks5RoutingUUID}",
  6552. "password": "${socks5RoutingUUID}"
  6553. }
  6554. ],
  6555. "domain_strategy":"${domainStrategy}"
  6556. }
  6557. ]
  6558. }
  6559. EOF
  6560. }
  6561. # 初始化sing-box rule配置
  6562. initSingBoxRules() {
  6563. local domainRules=[]
  6564. local ruleSet=[]
  6565. while read -r line; do
  6566. local geositeStatus
  6567. geositeStatus=$(curl -s "https://api.github.com/repos/SagerNet/sing-geosite/contents/geosite-${line}.srs?ref=rule-set" | jq .message)
  6568. if [[ "${geositeStatus}" == "null" ]]; then
  6569. ruleSet=$(echo "${ruleSet}" | jq -r ". += [{\"tag\":\"${line}_$2\",\"type\":\"remote\",\"format\":\"binary\",\"url\":\"https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-${line}.srs\",\"download_detour\":\"01_direct_outbound\"}]")
  6570. else
  6571. domainRules=$(echo "${domainRules}" | jq -r ". += [\"^([a-zA-Z0-9_-]+\\\.)*${line//./\\\\.}\"]")
  6572. fi
  6573. done < <(echo "$1" | tr ',' '\n' | grep -v '^$' | sort -n | uniq | paste -sd ',' | tr ',' '\n')
  6574. echo "{ \"domainRules\":${domainRules},\"ruleSet\":${ruleSet}}"
  6575. }
  6576. # socks5 inbound routing规则
  6577. setSocks5InboundRouting() {
  6578. singBoxConfigPath=/etc/v2ray-agent/sing-box/conf/config/
  6579. if [[ "$1" == "addRules" && ! -f "${singBoxConfigPath}socks5_inbound_route.json" && ! -f "${configPath}09_routing.json" ]]; then
  6580. echoContent red " ---> 请安装入站分流后再添加分流规则"
  6581. echoContent red " ---> 如已选择允许所有网站,请重新安装分流后设置规则"
  6582. exit 0
  6583. fi
  6584. local socks5InboundRoutingIPs=
  6585. if [[ "$1" == "addRules" ]]; then
  6586. socks5InboundRoutingIPs=$(jq .route.rules[0].source_ip_cidr "${singBoxConfigPath}socks5_inbound_route.json")
  6587. else
  6588. echoContent red "=============================================================="
  6589. echoContent skyBlue "请输入允许访问的IP地址,多个IP英文逗号隔开。例如:1.1.1.1,2.2.2.2\n"
  6590. read -r -p "IP:" socks5InboundRoutingIPs
  6591. if [[ -z "${socks5InboundRoutingIPs}" ]]; then
  6592. echoContent red " ---> IP不可为空"
  6593. exit 0
  6594. fi
  6595. socks5InboundRoutingIPs=$(echo "\"${socks5InboundRoutingIPs}"\" | jq -c '.|split(",")')
  6596. fi
  6597. echoContent red "=============================================================="
  6598. echoContent skyBlue "请输入要分流的域名\n"
  6599. echoContent yellow "支持Xray-core geosite匹配,支持sing-box1.8+ rule_set匹配\n"
  6600. echoContent yellow "非增量添加,会替换原有规则\n"
  6601. echoContent yellow "当输入的规则匹配到geosite或者rule_set后会使用相应的规则\n"
  6602. echoContent yellow "如无法匹配则,则使用domain精确匹配\n"
  6603. read -r -p "是否允许所有网站?请选择[y/n]:" socks5InboundRoutingDomainStatus
  6604. if [[ "${socks5InboundRoutingDomainStatus}" == "y" ]]; then
  6605. addSingBoxRouteRule "01_direct_outbound" "" "socks5_inbound_route"
  6606. local route=
  6607. route=$(jq ".route.rules[0].inbound = [\"socks5_inbound\"]" "${singBoxConfigPath}socks5_inbound_route.json")
  6608. route=$(echo "${route}" | jq ".route.rules[0].source_ip_cidr=${socks5InboundRoutingIPs}")
  6609. echo "${route}" | jq . >"${singBoxConfigPath}socks5_inbound_route.json"
  6610. addSingBoxOutbound block
  6611. addSingBoxOutbound "01_direct_outbound"
  6612. else
  6613. echoContent yellow "录入示例:netflix,openai,v2ray-agent.com\n"
  6614. read -r -p "域名:" socks5InboundRoutingDomain
  6615. if [[ -z "${socks5InboundRoutingDomain}" ]]; then
  6616. echoContent red " ---> 域名不可为空"
  6617. exit 0
  6618. fi
  6619. addSingBoxRouteRule "01_direct_outbound" "${socks5InboundRoutingDomain}" "socks5_inbound_route"
  6620. local route=
  6621. route=$(jq ".route.rules[0].inbound = [\"socks5_inbound\"]" "${singBoxConfigPath}socks5_inbound_route.json")
  6622. route=$(echo "${route}" | jq ".route.rules[0].source_ip_cidr=${socks5InboundRoutingIPs}")
  6623. echo "${route}" | jq . >"${singBoxConfigPath}socks5_inbound_route.json"
  6624. addSingBoxOutbound block
  6625. addSingBoxOutbound "01_direct_outbound"
  6626. fi
  6627. }
  6628. # socks5 出站
  6629. setSocks5Outbound() {
  6630. echoContent yellow "\n==================== 配置 Socks5 出站(转发机、代理机) =====================\n"
  6631. echo
  6632. read -r -p "请输入落地机IP地址:" socks5RoutingOutboundIP
  6633. if [[ -z "${socks5RoutingOutboundIP}" ]]; then
  6634. echoContent red " ---> IP不可为空"
  6635. exit 0
  6636. fi
  6637. echo
  6638. read -r -p "请输入落地机端口:" socks5RoutingOutboundPort
  6639. if [[ -z "${socks5RoutingOutboundPort}" ]]; then
  6640. echoContent red " ---> 端口不可为空"
  6641. exit 0
  6642. fi
  6643. echo
  6644. read -r -p "请输入用户名:" socks5RoutingOutboundUserName
  6645. if [[ -z "${socks5RoutingOutboundUserName}" ]]; then
  6646. echoContent red " ---> 用户名不可为空"
  6647. exit 0
  6648. fi
  6649. echo
  6650. read -r -p "请输入用户密码:" socks5RoutingOutboundPassword
  6651. if [[ -z "${socks5RoutingOutboundPassword}" ]]; then
  6652. echoContent red " ---> 用户密码不可为空"
  6653. exit 0
  6654. fi
  6655. echo
  6656. if [[ -n "${singBoxConfigPath}" ]]; then
  6657. cat <<EOF >"${singBoxConfigPath}socks5_outbound.json"
  6658. {
  6659. "outbounds":[
  6660. {
  6661. "type": "socks",
  6662. "tag":"socks5_outbound",
  6663. "server": "${socks5RoutingOutboundIP}",
  6664. "server_port": ${socks5RoutingOutboundPort},
  6665. "version": "5",
  6666. "username":"${socks5RoutingOutboundUserName}",
  6667. "password":"${socks5RoutingOutboundPassword}"
  6668. }
  6669. ]
  6670. }
  6671. EOF
  6672. fi
  6673. if [[ "${coreInstallType}" == "1" ]]; then
  6674. addXrayOutbound socks5_outbound
  6675. fi
  6676. }
  6677. # socks5 outbound routing规则
  6678. setSocks5OutboundRouting() {
  6679. if [[ "$1" == "addRules" && ! -f "${singBoxConfigPath}socks5_outbound_route.json" && ! -f "${configPath}09_routing.json" ]]; then
  6680. echoContent red " ---> 请安装出站分流后再添加分流规则"
  6681. exit 0
  6682. fi
  6683. echoContent red "=============================================================="
  6684. echoContent skyBlue "请输入要分流的域名\n"
  6685. echoContent yellow "支持Xray-core geosite匹配,支持sing-box1.8+ rule_set匹配\n"
  6686. echoContent yellow "非增量添加,会替换原有规则\n"
  6687. echoContent yellow "当输入的规则匹配到geosite或者rule_set后会使用相应的规则\n"
  6688. echoContent yellow "如无法匹配则,则使用domain精确匹配\n"
  6689. echoContent yellow "录入示例:netflix,openai,v2ray-agent.com\n"
  6690. read -r -p "域名:" socks5RoutingOutboundDomain
  6691. if [[ -z "${socks5RoutingOutboundDomain}" ]]; then
  6692. echoContent red " ---> IP不可为空"
  6693. exit 0
  6694. fi
  6695. addSingBoxRouteRule "socks5_outbound" "${socks5RoutingOutboundDomain}" "socks5_outbound_route"
  6696. addSingBoxOutbound "01_direct_outbound"
  6697. if [[ "${coreInstallType}" == "1" ]]; then
  6698. unInstallRouting "socks5_outbound" "outboundTag"
  6699. local domainRules=[]
  6700. while read -r line; do
  6701. if echo "${routingRule}" | grep -q "${line}"; then
  6702. echoContent yellow " ---> ${line}已存在,跳过"
  6703. else
  6704. local geositeStatus
  6705. geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message)
  6706. if [[ "${geositeStatus}" == "null" ]]; then
  6707. domainRules=$(echo "${domainRules}" | jq -r ". += [\"geosite:${line}\"]")
  6708. else
  6709. domainRules=$(echo "${domainRules}" | jq -r ". += [\"domain:${line}\"]")
  6710. fi
  6711. fi
  6712. done < <(echo "${socks5RoutingOutboundDomain}" | tr ',' '\n')
  6713. if [[ ! -f "${configPath}09_routing.json" ]]; then
  6714. cat <<EOF >${configPath}09_routing.json
  6715. {
  6716. "routing":{
  6717. "rules": []
  6718. }
  6719. }
  6720. EOF
  6721. fi
  6722. routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": ${domainRules},\"outboundTag\": \"socks5_outbound\"}]" ${configPath}09_routing.json)
  6723. echo "${routing}" | jq . >${configPath}09_routing.json
  6724. fi
  6725. }
  6726. # 设置VMess+WS+TLS【仅出站】
  6727. setVMessWSRoutingOutbounds() {
  6728. read -r -p "请输入VMess+WS+TLS的地址:" setVMessWSTLSAddress
  6729. echoContent red "=============================================================="
  6730. echoContent yellow "录入示例:netflix,openai\n"
  6731. read -r -p "请按照上面示例录入域名:" domainList
  6732. if [[ -z ${domainList} ]]; then
  6733. echoContent red " ---> 域名不可为空"
  6734. setVMessWSRoutingOutbounds
  6735. fi
  6736. if [[ -n "${setVMessWSTLSAddress}" ]]; then
  6737. removeXrayOutbound VMess-out
  6738. echo
  6739. read -r -p "请输入VMess+WS+TLS的端口:" setVMessWSTLSPort
  6740. echo
  6741. if [[ -z "${setVMessWSTLSPort}" ]]; then
  6742. echoContent red " ---> 端口不可为空"
  6743. fi
  6744. read -r -p "请输入VMess+WS+TLS的UUID:" setVMessWSTLSUUID
  6745. echo
  6746. if [[ -z "${setVMessWSTLSUUID}" ]]; then
  6747. echoContent red " ---> UUID不可为空"
  6748. fi
  6749. read -r -p "请输入VMess+WS+TLS的Path路径:" setVMessWSTLSPath
  6750. echo
  6751. if [[ -z "${setVMessWSTLSPath}" ]]; then
  6752. echoContent red " ---> 路径不可为空"
  6753. elif ! echo "${setVMessWSTLSPath}" | grep -q "/"; then
  6754. setVMessWSTLSPath="/${setVMessWSTLSPath}"
  6755. fi
  6756. addXrayOutbound "VMess-out"
  6757. addInstallRouting VMess-out outboundTag "${domainList}"
  6758. reloadCore
  6759. echoContent green " ---> 添加分流成功"
  6760. exit 0
  6761. fi
  6762. echoContent red " ---> 地址不可为空"
  6763. setVMessWSRoutingOutbounds
  6764. }
  6765. # 移除VMess+WS+TLS分流
  6766. removeVMessWSRouting() {
  6767. removeXrayOutbound VMess-out
  6768. unInstallRouting VMess-out outboundTag
  6769. reloadCore
  6770. echoContent green " ---> 卸载成功"
  6771. }
  6772. # 重启核心
  6773. reloadCore() {
  6774. readInstallType
  6775. if [[ "${coreInstallType}" == "1" ]]; then
  6776. handleXray stop
  6777. handleXray start
  6778. fi
  6779. if echo "${currentInstallProtocolType}" | grep -q ",20," || [[ "${coreInstallType}" == "2" || -n "${singBoxConfigPath}" ]]; then
  6780. handleSingBox stop
  6781. handleSingBox start
  6782. fi
  6783. }
  6784. # dns分流
  6785. dnsRouting() {
  6786. if [[ -z "${configPath}" ]]; then
  6787. echoContent red " ---> 未安装,请使用脚本安装"
  6788. menu
  6789. exit 0
  6790. fi
  6791. echoContent skyBlue "\n功能 1/${totalProgress} : DNS分流"
  6792. echoContent red "\n=============================================================="
  6793. echoContent yellow "# 注意事项"
  6794. echoContent yellow "# 使用教程:https://www.v2ray-agent.com/archives/1683226921000 \n"
  6795. echoContent yellow "1.添加"
  6796. echoContent yellow "2.卸载"
  6797. read -r -p "请选择:" selectType
  6798. case ${selectType} in
  6799. 1)
  6800. setUnlockDNS
  6801. ;;
  6802. 2)
  6803. removeUnlockDNS
  6804. ;;
  6805. esac
  6806. }
  6807. # SNI反向代理分流
  6808. sniRouting() {
  6809. if [[ -z "${configPath}" ]]; then
  6810. echoContent red " ---> 未安装,请使用脚本安装"
  6811. menu
  6812. exit 0
  6813. fi
  6814. echoContent skyBlue "\n功能 1/${totalProgress} : SNI反向代理分流"
  6815. echoContent red "\n=============================================================="
  6816. echoContent yellow "# 注意事项"
  6817. echoContent yellow "# 使用教程:https://www.v2ray-agent.com/archives/1683226921000 \n"
  6818. echoContent yellow "1.添加"
  6819. echoContent yellow "2.卸载"
  6820. read -r -p "请选择:" selectType
  6821. case ${selectType} in
  6822. 1)
  6823. setUnlockSNI
  6824. ;;
  6825. 2)
  6826. removeUnlockSNI
  6827. ;;
  6828. esac
  6829. }
  6830. # 设置SNI分流
  6831. setUnlockSNI() {
  6832. read -r -p "请输入分流的SNI IP:" setSNIP
  6833. if [[ -n ${setSNIP} ]]; then
  6834. echoContent red "=============================================================="
  6835. echoContent yellow "录入示例:netflix,disney,hulu"
  6836. read -r -p "请按照上面示例录入域名:" domainList
  6837. if [[ -n "${domainList}" ]]; then
  6838. local hosts={}
  6839. while read -r domain; do
  6840. hosts=$(echo "${hosts}" | jq -r ".\"geosite:${domain}\"=\"${setSNIP}\"")
  6841. done < <(echo "${domainList}" | tr ',' '\n')
  6842. cat <<EOF >${configPath}11_dns.json
  6843. {
  6844. "dns": {
  6845. "hosts":${hosts},
  6846. "servers": [
  6847. "8.8.8.8",
  6848. "1.1.1.1"
  6849. ]
  6850. }
  6851. }
  6852. EOF
  6853. echoContent red " ---> SNI反向代理分流成功"
  6854. reloadCore
  6855. else
  6856. echoContent red " ---> 域名不可为空"
  6857. fi
  6858. else
  6859. echoContent red " ---> SNI IP不可为空"
  6860. fi
  6861. exit 0
  6862. }
  6863. # 添加xray dns 配置
  6864. addXrayDNSConfig() {
  6865. local ip=$1
  6866. local domainList=$2
  6867. local domains=[]
  6868. while read -r line; do
  6869. local geositeStatus
  6870. geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message)
  6871. if [[ "${geositeStatus}" == "null" ]]; then
  6872. domains=$(echo "${domains}" | jq -r '. += ["geosite:'"${line}"'"]')
  6873. else
  6874. domains=$(echo "${domains}" | jq -r '. += ["domain:'"${line}"'"]')
  6875. fi
  6876. done < <(echo "${domainList}" | tr ',' '\n')
  6877. if [[ "${coreInstallType}" == "1" ]]; then
  6878. cat <<EOF >${configPath}11_dns.json
  6879. {
  6880. "dns": {
  6881. "servers": [
  6882. {
  6883. "address": "${ip}",
  6884. "port": 53,
  6885. "domains": ${domains}
  6886. },
  6887. "localhost"
  6888. ]
  6889. }
  6890. }
  6891. EOF
  6892. fi
  6893. }
  6894. # 添加sing-box dns配置
  6895. addSingBoxDNSConfig() {
  6896. local ip=$1
  6897. local domainList=$2
  6898. local rules=
  6899. rules=$(initSingBoxRules "${domainList}" "dns")
  6900. # domain精确匹配规则
  6901. local domainRules=
  6902. domainRules=$(echo "${rules}" | jq .domainRules)
  6903. # ruleSet规则集
  6904. local ruleSet=
  6905. ruleSet=$(echo "${rules}" | jq .ruleSet)
  6906. # ruleSet规则tag
  6907. local ruleSetTag=[]
  6908. if [[ "$(echo "${ruleSet}" | jq '.|length')" != "0" ]]; then
  6909. ruleSetTag=$(echo "${ruleSet}" | jq '.|map(.tag)')
  6910. fi
  6911. if [[ -n "${singBoxConfigPath}" ]]; then
  6912. cat <<EOF >"${singBoxConfigPath}dns.json"
  6913. {
  6914. "dns": {
  6915. "servers": [
  6916. {
  6917. "tag": "local",
  6918. "address": "local"
  6919. },
  6920. {
  6921. "tag": "dnsRouting",
  6922. "address": "${ip}"
  6923. }
  6924. ],
  6925. "rules": [
  6926. {
  6927. "rule_set": ${ruleSetTag},
  6928. "domain_regex": ${domainRules},
  6929. "server":"dnsRouting"
  6930. }
  6931. ]
  6932. },
  6933. "route":{
  6934. "rule_set":${ruleSet}
  6935. }
  6936. }
  6937. EOF
  6938. fi
  6939. }
  6940. # 设置dns
  6941. setUnlockDNS() {
  6942. read -r -p "请输入分流的DNS:" setDNS
  6943. if [[ -n ${setDNS} ]]; then
  6944. echoContent red "=============================================================="
  6945. echoContent yellow "录入示例:netflix,disney,hulu"
  6946. read -r -p "请按照上面示例录入域名:" domainList
  6947. if [[ "${coreInstallType}" == "1" ]]; then
  6948. addXrayDNSConfig "${setDNS}" "${domainList}"
  6949. fi
  6950. if [[ -n "${singBoxConfigPath}" ]]; then
  6951. addSingBoxOutbound 01_direct_outbound
  6952. addSingBoxDNSConfig "${setDNS}" "${domainList}"
  6953. fi
  6954. reloadCore
  6955. echoContent yellow "\n ---> 如还无法观看可以尝试以下两种方案"
  6956. echoContent yellow " 1.重启vps"
  6957. echoContent yellow " 2.卸载dns解锁后,修改本地的[/etc/resolv.conf]DNS设置并重启vps\n"
  6958. else
  6959. echoContent red " ---> dns不可为空"
  6960. fi
  6961. exit 0
  6962. }
  6963. # 移除 DNS分流
  6964. removeUnlockDNS() {
  6965. if [[ "${coreInstallType}" == "1" && -f "${configPath}11_dns.json" ]]; then
  6966. cat <<EOF >${configPath}11_dns.json
  6967. {
  6968. "dns": {
  6969. "servers": [
  6970. "localhost"
  6971. ]
  6972. }
  6973. }
  6974. EOF
  6975. fi
  6976. if [[ "${coreInstallType}" == "2" && -f "${singBoxConfigPath}dns.json" ]]; then
  6977. cat <<EOF >${singBoxConfigPath}dns.json
  6978. {
  6979. "dns": {
  6980. "servers":[
  6981. {
  6982. "address":"local"
  6983. }
  6984. ]
  6985. }
  6986. }
  6987. EOF
  6988. fi
  6989. reloadCore
  6990. echoContent green " ---> 卸载成功"
  6991. exit 0
  6992. }
  6993. # 移除SNI分流
  6994. removeUnlockSNI() {
  6995. cat <<EOF >${configPath}11_dns.json
  6996. {
  6997. "dns": {
  6998. "servers": [
  6999. "localhost"
  7000. ]
  7001. }
  7002. }
  7003. EOF
  7004. reloadCore
  7005. echoContent green " ---> 卸载成功"
  7006. exit 0
  7007. }
  7008. # sing-box 个性化安装
  7009. customSingBoxInstall() {
  7010. echoContent skyBlue "\n========================个性化安装============================"
  7011. echoContent yellow "0.VLESS+Vision+TCP"
  7012. echoContent yellow "1.VLESS+TLS+WS[仅CDN推荐]"
  7013. echoContent yellow "3.VMess+TLS+WS[仅CDN推荐]"
  7014. echoContent yellow "4.Trojan+TLS[不推荐]"
  7015. echoContent yellow "6.Hysteria2"
  7016. echoContent yellow "7.VLESS+Reality+Vision"
  7017. echoContent yellow "8.VLESS+Reality+gRPC"
  7018. echoContent yellow "9.Tuic"
  7019. echoContent yellow "10.Naive"
  7020. echoContent yellow "11.VMess+TLS+HTTPUpgrade"
  7021. echoContent yellow "13.anytls"
  7022. read -r -p "请选择[多选],[例如:1,2,3]:" selectCustomInstallType
  7023. echoContent skyBlue "--------------------------------------------------------------"
  7024. if echo "${selectCustomInstallType}" | grep -q ","; then
  7025. echoContent red " ---> 请使用英文逗号分隔"
  7026. exit 0
  7027. fi
  7028. if [[ "${selectCustomInstallType}" != "10" ]] && [[ "${selectCustomInstallType}" != "11" ]] && [[ "${selectCustomInstallType}" != "13" ]] && ((${#selectCustomInstallType} >= 2)) && ! echo "${selectCustomInstallType}" | grep -q ","; then
  7029. echoContent red " ---> 多选请使用英文逗号分隔"
  7030. exit 0
  7031. fi
  7032. if [[ "${selectCustomInstallType: -1}" != "," ]]; then
  7033. selectCustomInstallType="${selectCustomInstallType},"
  7034. fi
  7035. if [[ "${selectCustomInstallType:0:1}" != "," ]]; then
  7036. selectCustomInstallType=",${selectCustomInstallType},"
  7037. fi
  7038. if [[ "${selectCustomInstallType//,/}" =~ ^[0-9]+$ ]]; then
  7039. readLastInstallationConfig
  7040. unInstallSubscribe
  7041. totalProgress=9
  7042. installTools 1
  7043. # 申请tls
  7044. if echo "${selectCustomInstallType}" | grep -q -E ",0,|,1,|,3,|,4,|,6,|,9,|,10,|,11,|,13,"; then
  7045. initTLSNginxConfig 2
  7046. installTLS 3
  7047. handleNginx stop
  7048. fi
  7049. installSingBox 4
  7050. installSingBoxService 5
  7051. initSingBoxConfig custom 6
  7052. cleanUp xrayDel
  7053. installCronTLS 7
  7054. handleSingBox stop
  7055. handleSingBox start
  7056. handleNginx stop
  7057. handleNginx start
  7058. # 生成账号
  7059. checkGFWStatue 8
  7060. showAccounts 9
  7061. else
  7062. echoContent red " ---> 输入不合法"
  7063. customSingBoxInstall
  7064. fi
  7065. }
  7066. # Xray-core个性化安装
  7067. customXrayInstall() {
  7068. echoContent skyBlue "\n========================个性化安装============================"
  7069. echoContent yellow "VLESS前置,默认安装0,无域名安装Reality只选择7即可"
  7070. echoContent yellow "0.VLESS+TLS_Vision+TCP[推荐]"
  7071. echoContent yellow "1.VLESS+TLS+WS[仅CDN推荐]"
  7072. # echoContent yellow "2.Trojan+TLS+gRPC[仅CDN推荐]"
  7073. echoContent yellow "3.VMess+TLS+WS[仅CDN推荐]"
  7074. echoContent yellow "4.Trojan+TLS[不推荐]"
  7075. echoContent yellow "5.VLESS+TLS+gRPC[仅CDN推荐]"
  7076. echoContent yellow "7.VLESS+Reality+uTLS+Vision[推荐]"
  7077. # echoContent yellow "8.VLESS+Reality+gRPC"
  7078. echoContent yellow "12.VLESS+XHTTP+TLS"
  7079. read -r -p "请选择[多选],[例如:1,2,3]:" selectCustomInstallType
  7080. echoContent skyBlue "--------------------------------------------------------------"
  7081. if echo "${selectCustomInstallType}" | grep -q ","; then
  7082. echoContent red " ---> 请使用英文逗号分隔"
  7083. exit 0
  7084. fi
  7085. if [[ "${selectCustomInstallType}" != "12" ]] && ((${#selectCustomInstallType} >= 2)) && ! echo "${selectCustomInstallType}" | grep -q ","; then
  7086. echoContent red " ---> 多选请使用英文逗号分隔"
  7087. exit 0
  7088. fi
  7089. if [[ "${selectCustomInstallType}" == "7" ]]; then
  7090. selectCustomInstallType=",${selectCustomInstallType},"
  7091. else
  7092. if ! echo "${selectCustomInstallType}" | grep -q "0,"; then
  7093. selectCustomInstallType=",0,${selectCustomInstallType},"
  7094. else
  7095. selectCustomInstallType=",${selectCustomInstallType},"
  7096. fi
  7097. fi
  7098. if [[ "${selectCustomInstallType:0:1}" != "," ]]; then
  7099. selectCustomInstallType=",${selectCustomInstallType},"
  7100. fi
  7101. if [[ "${selectCustomInstallType//,/}" =~ ^[0-7]+$ ]]; then
  7102. readLastInstallationConfig
  7103. unInstallSubscribe
  7104. checkBTPanel
  7105. check1Panel
  7106. totalProgress=12
  7107. installTools 1
  7108. if [[ -n "${btDomain}" ]]; then
  7109. echoContent skyBlue "\n进度 3/${totalProgress} : 检测到宝塔面板/1Panel,跳过申请TLS步骤"
  7110. handleXray stop
  7111. if [[ "${selectCustomInstallType}" != ",7," ]]; then
  7112. customPortFunction
  7113. fi
  7114. else
  7115. # 申请tls
  7116. if [[ "${selectCustomInstallType}" != ",7," ]]; then
  7117. initTLSNginxConfig 2
  7118. handleXray stop
  7119. installTLS 3
  7120. else
  7121. echoContent skyBlue "\n进度 2/${totalProgress} : 检测到仅安装Reality,跳过TLS证书步骤"
  7122. fi
  7123. fi
  7124. handleNginx stop
  7125. # 随机path
  7126. if echo "${selectCustomInstallType}" | grep -qE ",1,|,2,|,3,|,5,|,12,"; then
  7127. randomPathFunction 4
  7128. fi
  7129. if [[ -n "${btDomain}" ]]; then
  7130. echoContent skyBlue "\n进度 6/${totalProgress} : 检测到宝塔面板/1Panel,跳过伪装网站"
  7131. else
  7132. nginxBlog 6
  7133. fi
  7134. if [[ "${selectCustomInstallType}" != ",7," ]]; then
  7135. updateRedirectNginxConf
  7136. handleNginx start
  7137. fi
  7138. # 安装Xray
  7139. installXray 7 false
  7140. installXrayService 8
  7141. initXrayConfig custom 9
  7142. cleanUp singBoxDel
  7143. if [[ "${selectCustomInstallType}" != ",7," ]]; then
  7144. installCronTLS 10
  7145. fi
  7146. handleXray stop
  7147. handleXray start
  7148. # 生成账号
  7149. checkGFWStatue 11
  7150. showAccounts 12
  7151. else
  7152. echoContent red " ---> 输入不合法"
  7153. customXrayInstall
  7154. fi
  7155. }
  7156. # 选择核心安装sing-box、xray-core
  7157. selectCoreInstall() {
  7158. echoContent skyBlue "\n功能 1/${totalProgress} : 选择核心安装"
  7159. echoContent red "\n=============================================================="
  7160. echoContent yellow "1.Xray-core"
  7161. echoContent yellow "2.sing-box"
  7162. echoContent red "=============================================================="
  7163. read -r -p "请选择:" selectCoreType
  7164. case ${selectCoreType} in
  7165. 1)
  7166. if [[ "${selectInstallType}" == "2" ]]; then
  7167. customXrayInstall
  7168. else
  7169. xrayCoreInstall
  7170. fi
  7171. ;;
  7172. 2)
  7173. if [[ "${selectInstallType}" == "2" ]]; then
  7174. customSingBoxInstall
  7175. else
  7176. singBoxInstall
  7177. fi
  7178. ;;
  7179. *)
  7180. echoContent red ' ---> 选择错误,重新选择'
  7181. selectCoreInstall
  7182. ;;
  7183. esac
  7184. }
  7185. # xray-core 安装
  7186. xrayCoreInstall() {
  7187. readLastInstallationConfig
  7188. unInstallSubscribe
  7189. checkBTPanel
  7190. check1Panel
  7191. selectCustomInstallType=
  7192. totalProgress=12
  7193. installTools 2
  7194. if [[ -n "${btDomain}" ]]; then
  7195. echoContent skyBlue "\n进度 3/${totalProgress} : 检测到宝塔面板/1Panel,跳过申请TLS步骤"
  7196. handleXray stop
  7197. customPortFunction
  7198. else
  7199. # 申请tls
  7200. initTLSNginxConfig 3
  7201. handleXray stop
  7202. installTLS 4
  7203. fi
  7204. handleNginx stop
  7205. randomPathFunction 5
  7206. # 安装Xray
  7207. installXray 6 false
  7208. installXrayService 7
  7209. initXrayConfig all 8
  7210. cleanUp singBoxDel
  7211. installCronTLS 9
  7212. if [[ -n "${btDomain}" ]]; then
  7213. echoContent skyBlue "\n进度 11/${totalProgress} : 检测到宝塔面板/1Panel,跳过伪装网站"
  7214. else
  7215. nginxBlog 10
  7216. fi
  7217. updateRedirectNginxConf
  7218. handleXray stop
  7219. sleep 2
  7220. handleXray start
  7221. handleNginx start
  7222. # 生成账号
  7223. checkGFWStatue 11
  7224. showAccounts 12
  7225. }
  7226. # sing-box 全部安装
  7227. singBoxInstall() {
  7228. readLastInstallationConfig
  7229. unInstallSubscribe
  7230. checkBTPanel
  7231. check1Panel
  7232. selectCustomInstallType=
  7233. totalProgress=8
  7234. installTools 2
  7235. if [[ -n "${btDomain}" ]]; then
  7236. echoContent skyBlue "\n进度 3/${totalProgress} : 检测到宝塔面板/1Panel,跳过申请TLS步骤"
  7237. handleXray stop
  7238. customPortFunction
  7239. else
  7240. # 申请tls
  7241. initTLSNginxConfig 3
  7242. handleXray stop
  7243. installTLS 4
  7244. fi
  7245. handleNginx stop
  7246. installSingBox 5
  7247. installSingBoxService 6
  7248. initSingBoxConfig all 7
  7249. cleanUp xrayDel
  7250. installCronTLS 8
  7251. handleSingBox stop
  7252. handleSingBox start
  7253. handleNginx stop
  7254. handleNginx start
  7255. # 生成账号
  7256. showAccounts 9
  7257. }
  7258. # 核心管理
  7259. coreVersionManageMenu() {
  7260. if [[ -z "${coreInstallType}" ]]; then
  7261. echoContent red "\n ---> 没有检测到安装目录,请执行脚本安装内容"
  7262. menu
  7263. exit 0
  7264. fi
  7265. echoContent skyBlue "\n功能 1/1 : 请选择核心"
  7266. echoContent red "\n=============================================================="
  7267. echoContent yellow "1.Xray-core"
  7268. echoContent yellow "2.sing-box"
  7269. echoContent red "=============================================================="
  7270. read -r -p "请输入:" selectCore
  7271. if [[ "${selectCore}" == "1" ]]; then
  7272. xrayVersionManageMenu 1
  7273. elif [[ "${selectCore}" == "2" ]]; then
  7274. singBoxVersionManageMenu 1
  7275. fi
  7276. }
  7277. # 定时任务检查
  7278. cronFunction() {
  7279. if [[ "${cronName}" == "RenewTLS" ]]; then
  7280. renewalTLS
  7281. exit 0
  7282. elif [[ "${cronName}" == "UpdateGeo" ]]; then
  7283. updateGeoSite >>/etc/v2ray-agent/crontab_updateGeoSite.log
  7284. echoContent green " ---> geo更新日期:$(date "+%F %H:%M:%S")" >>/etc/v2ray-agent/crontab_updateGeoSite.log
  7285. exit 0
  7286. fi
  7287. }
  7288. # 账号管理
  7289. manageAccount() {
  7290. echoContent skyBlue "\n功能 1/${totalProgress} : 账号管理"
  7291. if [[ -z "${configPath}" ]]; then
  7292. echoContent red " ---> 未安装"
  7293. exit 0
  7294. fi
  7295. echoContent red "\n=============================================================="
  7296. echoContent yellow "# 添加单个用户时可自定义email和uuid"
  7297. echoContent yellow "# 如安装了Hysteria或者Tuic,账号会同时添加到相应的类型下面\n"
  7298. echoContent yellow "1.查看账号"
  7299. echoContent yellow "2.查看订阅"
  7300. echoContent yellow "3.管理其他订阅"
  7301. echoContent yellow "4.添加用户"
  7302. echoContent yellow "5.删除用户"
  7303. echoContent red "=============================================================="
  7304. read -r -p "请输入:" manageAccountStatus
  7305. if [[ "${manageAccountStatus}" == "1" ]]; then
  7306. showAccounts 1
  7307. elif [[ "${manageAccountStatus}" == "2" ]]; then
  7308. subscribe
  7309. elif [[ "${manageAccountStatus}" == "3" ]]; then
  7310. addSubscribeMenu 1
  7311. elif [[ "${manageAccountStatus}" == "4" ]]; then
  7312. addUser
  7313. elif [[ "${manageAccountStatus}" == "5" ]]; then
  7314. removeUser
  7315. else
  7316. echoContent red " ---> 选择错误"
  7317. fi
  7318. }
  7319. # 安装订阅
  7320. installSubscribe() {
  7321. readNginxSubscribe
  7322. local nginxSubscribeListen=
  7323. local nginxSubscribeSSL=
  7324. local serverName=
  7325. local SSLType=
  7326. local listenIPv6=
  7327. if [[ -z "${subscribePort}" ]]; then
  7328. nginxVersion=$(nginx -v 2>&1)
  7329. if echo "${nginxVersion}" | grep -q "not found" || [[ -z "${nginxVersion}" ]]; then
  7330. echoContent yellow "未检测到nginx,无法使用订阅服务\n"
  7331. read -r -p "是否安装[y/n]?" installNginxStatus
  7332. if [[ "${installNginxStatus}" == "y" ]]; then
  7333. installNginxTools
  7334. else
  7335. echoContent red " ---> 放弃安装nginx\n"
  7336. exit 0
  7337. fi
  7338. fi
  7339. echoContent yellow "开始配置订阅,请输入订阅的端口\n"
  7340. mapfile -t result < <(initSingBoxPort "${subscribePort}")
  7341. echo
  7342. echoContent yellow " ---> 开始配置订阅的伪装站点\n"
  7343. nginxBlog
  7344. echo
  7345. local httpSubscribeStatus=
  7346. if ! echo "${selectCustomInstallType}" | grep -qE ",0,|,1,|,2,|,3,|,4,|,5,|,6,|,9,|,10,|,11,|,13," && ! echo "${currentInstallProtocolType}" | grep -qE ",0,|,1,|,2,|,3,|,4,|,5,|,6,|,9,|,10,|,11,|,13," && [[ -z "${domain}" ]]; then
  7347. httpSubscribeStatus=true
  7348. fi
  7349. if [[ "${httpSubscribeStatus}" == "true" ]]; then
  7350. echoContent yellow "未发现tls证书,使用无加密订阅,可能被运营商拦截,请注意风险。"
  7351. echo
  7352. read -r -p "是否使用http订阅[y/n]?" addNginxSubscribeStatus
  7353. echo
  7354. if [[ "${addNginxSubscribeStatus}" != "y" ]]; then
  7355. echoContent yellow " ---> 退出安装"
  7356. exit
  7357. fi
  7358. else
  7359. local subscribeServerName=
  7360. if [[ -n "${currentHost}" ]]; then
  7361. subscribeServerName="${currentHost}"
  7362. else
  7363. subscribeServerName="${domain}"
  7364. fi
  7365. SSLType="ssl"
  7366. serverName="server_name ${subscribeServerName};"
  7367. nginxSubscribeSSL="ssl_certificate /etc/v2ray-agent/tls/${subscribeServerName}.crt;ssl_certificate_key /etc/v2ray-agent/tls/${subscribeServerName}.key;"
  7368. fi
  7369. if [[ -n "$(curl --connect-timeout 2 -s -6 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2)" ]]; then
  7370. listenIPv6="listen [::]:${result[-1]} ${SSLType};"
  7371. fi
  7372. if echo "${nginxVersion}" | grep -q "1.25" && [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $3}') -gt 0 ]] || [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $2}') -gt 25 ]]; then
  7373. nginxSubscribeListen="listen ${result[-1]} ${SSLType} so_keepalive=on;http2 on;${listenIPv6}"
  7374. else
  7375. nginxSubscribeListen="listen ${result[-1]} ${SSLType} so_keepalive=on;${listenIPv6}"
  7376. fi
  7377. cat <<EOF >${nginxConfigPath}subscribe.conf
  7378. server {
  7379. ${nginxSubscribeListen}
  7380. ${serverName}
  7381. ${nginxSubscribeSSL}
  7382. ssl_protocols TLSv1.2 TLSv1.3;
  7383. ssl_ciphers TLS13_AES_128_GCM_SHA256:TLS13_AES_256_GCM_SHA384:TLS13_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;
  7384. ssl_prefer_server_ciphers on;
  7385. resolver 1.1.1.1 valid=60s;
  7386. resolver_timeout 2s;
  7387. client_max_body_size 100m;
  7388. root ${nginxStaticPath};
  7389. location ~ ^/s/(clashMeta|default|clashMetaProfiles|sing-box|sing-box_profiles)/(.*) {
  7390. default_type 'text/plain; charset=utf-8';
  7391. alias /etc/v2ray-agent/subscribe/\$1/\$2;
  7392. }
  7393. location / {
  7394. }
  7395. }
  7396. EOF
  7397. bootStartup nginx
  7398. handleNginx stop
  7399. handleNginx start
  7400. fi
  7401. if [[ -z $(pgrep -f "nginx") ]]; then
  7402. handleNginx start
  7403. fi
  7404. }
  7405. # 卸载订阅
  7406. unInstallSubscribe() {
  7407. rm -rf ${nginxConfigPath}subscribe.conf >/dev/null 2>&1
  7408. }
  7409. # 添加订阅
  7410. addSubscribeMenu() {
  7411. echoContent skyBlue "\n===================== 添加其他机器订阅 ======================="
  7412. echoContent yellow "1.添加"
  7413. echoContent yellow "2.移除"
  7414. echoContent red "=============================================================="
  7415. read -r -p "请选择:" addSubscribeStatus
  7416. if [[ "${addSubscribeStatus}" == "1" ]]; then
  7417. addOtherSubscribe
  7418. elif [[ "${addSubscribeStatus}" == "2" ]]; then
  7419. if [[ ! -f "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" ]]; then
  7420. echoContent green " ---> 未安装其他订阅"
  7421. exit 0
  7422. fi
  7423. grep -v '^$' "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" | awk '{print NR""":"$0}'
  7424. read -r -p "请选择要删除的订阅编号[仅支持单个删除]:" delSubscribeIndex
  7425. if [[ -z "${delSubscribeIndex}" ]]; then
  7426. echoContent green " ---> 不可以为空"
  7427. exit 0
  7428. fi
  7429. sed -i "$((delSubscribeIndex))d" "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" >/dev/null 2>&1
  7430. echoContent green " ---> 其他机器订阅删除成功"
  7431. subscribe
  7432. fi
  7433. }
  7434. # 添加其他机器clashMeta订阅
  7435. addOtherSubscribe() {
  7436. echoContent yellow "#注意事项:"
  7437. echoContent yellow "请仔细阅读以下文章: https://www.v2ray-agent.com/archives/1681804748677"
  7438. echoContent skyBlue "录入示例:www.v2ray-agent.com:443:vps1\n"
  7439. read -r -p "请输入域名 端口 机器别名:" remoteSubscribeUrl
  7440. if [[ -z "${remoteSubscribeUrl}" ]]; then
  7441. echoContent red " ---> 不可为空"
  7442. addOtherSubscribe
  7443. elif ! echo "${remoteSubscribeUrl}" | grep -q ":"; then
  7444. echoContent red " ---> 规则不合法"
  7445. else
  7446. if [[ -f "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" ]] && grep -q "${remoteSubscribeUrl}" /etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl; then
  7447. echoContent red " ---> 此订阅已添加"
  7448. exit 0
  7449. fi
  7450. echo
  7451. read -r -p "是否是HTTP订阅?[y/n]" httpSubscribeStatus
  7452. if [[ "${httpSubscribeStatus}" == "y" ]]; then
  7453. remoteSubscribeUrl="${remoteSubscribeUrl}:http"
  7454. fi
  7455. echo "${remoteSubscribeUrl}" >>/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl
  7456. subscribe
  7457. fi
  7458. }
  7459. # clashMeta配置文件
  7460. clashMetaConfig() {
  7461. local url=$1
  7462. local id=$2
  7463. cat <<EOF >"/etc/v2ray-agent/subscribe/clashMetaProfiles/${id}"
  7464. log-level: debug
  7465. mode: rule
  7466. ipv6: true
  7467. mixed-port: 7890
  7468. allow-lan: true
  7469. bind-address: "*"
  7470. lan-allowed-ips:
  7471. - 0.0.0.0/0
  7472. - ::/0
  7473. find-process-mode: strict
  7474. external-controller: 0.0.0.0:9090
  7475. geox-url:
  7476. geoip: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat"
  7477. geosite: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat"
  7478. mmdb: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb"
  7479. geo-auto-update: true
  7480. geo-update-interval: 24
  7481. external-controller-cors:
  7482. allow-private-network: true
  7483. global-client-fingerprint: chrome
  7484. profile:
  7485. store-selected: true
  7486. store-fake-ip: true
  7487. sniffer:
  7488. enable: true
  7489. override-destination: false
  7490. sniff:
  7491. QUIC:
  7492. ports: [ 443 ]
  7493. TLS:
  7494. ports: [ 443 ]
  7495. HTTP:
  7496. ports: [80]
  7497. dns:
  7498. enable: true
  7499. prefer-h3: false
  7500. listen: 0.0.0.0:1053
  7501. ipv6: true
  7502. enhanced-mode: fake-ip
  7503. fake-ip-range: 198.18.0.1/16
  7504. fake-ip-filter:
  7505. - '*.lan'
  7506. - '*.local'
  7507. - 'dns.google'
  7508. - "localhost.ptlogin2.qq.com"
  7509. use-hosts: true
  7510. nameserver:
  7511. - https://1.1.1.1/dns-query
  7512. - https://8.8.8.8/dns-query
  7513. - 1.1.1.1
  7514. - 8.8.8.8
  7515. proxy-server-nameserver:
  7516. - https://223.5.5.5/dns-query
  7517. - https://1.12.12.12/dns-query
  7518. nameserver-policy:
  7519. "geosite:cn,private":
  7520. - https://doh.pub/dns-query
  7521. - https://dns.alidns.com/dns-query
  7522. proxy-providers:
  7523. ${subscribeSalt}_provider:
  7524. type: http
  7525. path: ./${subscribeSalt}_provider.yaml
  7526. url: ${url}
  7527. interval: 3600
  7528. proxy: DIRECT
  7529. health-check:
  7530. enable: true
  7531. url: https://cp.cloudflare.com/generate_204
  7532. interval: 300
  7533. proxy-groups:
  7534. - name: 手动切换
  7535. type: select
  7536. use:
  7537. - ${subscribeSalt}_provider
  7538. proxies: null
  7539. - name: 自动选择
  7540. type: url-test
  7541. url: http://www.gstatic.com/generate_204
  7542. interval: 36000
  7543. tolerance: 50
  7544. use:
  7545. - ${subscribeSalt}_provider
  7546. proxies: null
  7547. - name: 全球代理
  7548. type: select
  7549. use:
  7550. - ${subscribeSalt}_provider
  7551. proxies:
  7552. - 手动切换
  7553. - 自动选择
  7554. - name: 流媒体
  7555. type: select
  7556. use:
  7557. - ${subscribeSalt}_provider
  7558. proxies:
  7559. - 手动切换
  7560. - 自动选择
  7561. - DIRECT
  7562. - name: DNS_Proxy
  7563. type: select
  7564. use:
  7565. - ${subscribeSalt}_provider
  7566. proxies:
  7567. - 自动选择
  7568. - DIRECT
  7569. - name: Telegram
  7570. type: select
  7571. use:
  7572. - ${subscribeSalt}_provider
  7573. proxies:
  7574. - 手动切换
  7575. - 自动选择
  7576. - name: Google
  7577. type: select
  7578. use:
  7579. - ${subscribeSalt}_provider
  7580. proxies:
  7581. - 手动切换
  7582. - 自动选择
  7583. - DIRECT
  7584. - name: YouTube
  7585. type: select
  7586. use:
  7587. - ${subscribeSalt}_provider
  7588. proxies:
  7589. - 手动切换
  7590. - 自动选择
  7591. - name: Netflix
  7592. type: select
  7593. use:
  7594. - ${subscribeSalt}_provider
  7595. proxies:
  7596. - 流媒体
  7597. - 手动切换
  7598. - 自动选择
  7599. - name: Spotify
  7600. type: select
  7601. use:
  7602. - ${subscribeSalt}_provider
  7603. proxies:
  7604. - 流媒体
  7605. - 手动切换
  7606. - 自动选择
  7607. - DIRECT
  7608. - name: HBO
  7609. type: select
  7610. use:
  7611. - ${subscribeSalt}_provider
  7612. proxies:
  7613. - 流媒体
  7614. - 手动切换
  7615. - 自动选择
  7616. - name: Bing
  7617. type: select
  7618. use:
  7619. - ${subscribeSalt}_provider
  7620. proxies:
  7621. - 自动选择
  7622. - name: OpenAI
  7623. type: select
  7624. use:
  7625. - ${subscribeSalt}_provider
  7626. proxies:
  7627. - 自动选择
  7628. - 手动切换
  7629. - name: ClaudeAI
  7630. type: select
  7631. use:
  7632. - ${subscribeSalt}_provider
  7633. proxies:
  7634. - 自动选择
  7635. - 手动切换
  7636. - name: Disney
  7637. type: select
  7638. use:
  7639. - ${subscribeSalt}_provider
  7640. proxies:
  7641. - 流媒体
  7642. - 手动切换
  7643. - 自动选择
  7644. - name: GitHub
  7645. type: select
  7646. use:
  7647. - ${subscribeSalt}_provider
  7648. proxies:
  7649. - 手动切换
  7650. - 自动选择
  7651. - DIRECT
  7652. - name: 国内媒体
  7653. type: select
  7654. use:
  7655. - ${subscribeSalt}_provider
  7656. proxies:
  7657. - DIRECT
  7658. - name: 本地直连
  7659. type: select
  7660. use:
  7661. - ${subscribeSalt}_provider
  7662. proxies:
  7663. - DIRECT
  7664. - 自动选择
  7665. - name: 漏网之鱼
  7666. type: select
  7667. use:
  7668. - ${subscribeSalt}_provider
  7669. proxies:
  7670. - DIRECT
  7671. - 手动切换
  7672. - 自动选择
  7673. rule-providers:
  7674. lan:
  7675. type: http
  7676. behavior: classical
  7677. interval: 86400
  7678. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Lan/Lan.yaml
  7679. path: ./Rules/lan.yaml
  7680. reject:
  7681. type: http
  7682. behavior: domain
  7683. url: https://gh-proxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/reject.txt
  7684. path: ./ruleset/reject.yaml
  7685. interval: 86400
  7686. proxy:
  7687. type: http
  7688. behavior: domain
  7689. url: https://gh-proxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/proxy.txt
  7690. path: ./ruleset/proxy.yaml
  7691. interval: 86400
  7692. direct:
  7693. type: http
  7694. behavior: domain
  7695. url: https://gh-proxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/direct.txt
  7696. path: ./ruleset/direct.yaml
  7697. interval: 86400
  7698. private:
  7699. type: http
  7700. behavior: domain
  7701. url: https://gh-proxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/private.txt
  7702. path: ./ruleset/private.yaml
  7703. interval: 86400
  7704. gfw:
  7705. type: http
  7706. behavior: domain
  7707. url: https://gh-proxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/gfw.txt
  7708. path: ./ruleset/gfw.yaml
  7709. interval: 86400
  7710. greatfire:
  7711. type: http
  7712. behavior: domain
  7713. url: https://gh-proxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/greatfire.txt
  7714. path: ./ruleset/greatfire.yaml
  7715. interval: 86400
  7716. tld-not-cn:
  7717. type: http
  7718. behavior: domain
  7719. url: https://gh-proxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/tld-not-cn.txt
  7720. path: ./ruleset/tld-not-cn.yaml
  7721. interval: 86400
  7722. telegramcidr:
  7723. type: http
  7724. behavior: ipcidr
  7725. url: https://gh-proxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/telegramcidr.txt
  7726. path: ./ruleset/telegramcidr.yaml
  7727. interval: 86400
  7728. applications:
  7729. type: http
  7730. behavior: classical
  7731. url: https://gh-proxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/applications.txt
  7732. path: ./ruleset/applications.yaml
  7733. interval: 86400
  7734. Disney:
  7735. type: http
  7736. behavior: classical
  7737. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Disney/Disney.yaml
  7738. path: ./ruleset/disney.yaml
  7739. interval: 86400
  7740. Netflix:
  7741. type: http
  7742. behavior: classical
  7743. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Netflix/Netflix.yaml
  7744. path: ./ruleset/netflix.yaml
  7745. interval: 86400
  7746. YouTube:
  7747. type: http
  7748. behavior: classical
  7749. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/YouTube/YouTube.yaml
  7750. path: ./ruleset/youtube.yaml
  7751. interval: 86400
  7752. HBO:
  7753. type: http
  7754. behavior: classical
  7755. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/HBO/HBO.yaml
  7756. path: ./ruleset/hbo.yaml
  7757. interval: 86400
  7758. OpenAI:
  7759. type: http
  7760. behavior: classical
  7761. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/OpenAI/OpenAI.yaml
  7762. path: ./ruleset/openai.yaml
  7763. interval: 86400
  7764. ClaudeAI:
  7765. type: http
  7766. behavior: classical
  7767. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Claude/Claude.yaml
  7768. path: ./ruleset/claudeai.yaml
  7769. interval: 86400
  7770. Bing:
  7771. type: http
  7772. behavior: classical
  7773. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Bing/Bing.yaml
  7774. path: ./ruleset/bing.yaml
  7775. interval: 86400
  7776. Google:
  7777. type: http
  7778. behavior: classical
  7779. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Google/Google.yaml
  7780. path: ./ruleset/google.yaml
  7781. interval: 86400
  7782. GitHub:
  7783. type: http
  7784. behavior: classical
  7785. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/GitHub/GitHub.yaml
  7786. path: ./ruleset/github.yaml
  7787. interval: 86400
  7788. Spotify:
  7789. type: http
  7790. behavior: classical
  7791. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Spotify/Spotify.yaml
  7792. path: ./ruleset/spotify.yaml
  7793. interval: 86400
  7794. ChinaMaxDomain:
  7795. type: http
  7796. behavior: domain
  7797. interval: 86400
  7798. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/ChinaMax/ChinaMax_Domain.yaml
  7799. path: ./Rules/ChinaMaxDomain.yaml
  7800. ChinaMaxIPNoIPv6:
  7801. type: http
  7802. behavior: ipcidr
  7803. interval: 86400
  7804. url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/ChinaMax/ChinaMax_IP_No_IPv6.yaml
  7805. path: ./Rules/ChinaMaxIPNoIPv6.yaml
  7806. rules:
  7807. - RULE-SET,YouTube,YouTube,no-resolve
  7808. - RULE-SET,Google,Google,no-resolve
  7809. - RULE-SET,GitHub,GitHub
  7810. - RULE-SET,telegramcidr,Telegram,no-resolve
  7811. - RULE-SET,Spotify,Spotify,no-resolve
  7812. - RULE-SET,Netflix,Netflix
  7813. - RULE-SET,HBO,HBO
  7814. - RULE-SET,Bing,Bing
  7815. - RULE-SET,OpenAI,OpenAI
  7816. - RULE-SET,ClaudeAI,ClaudeAI
  7817. - RULE-SET,Disney,Disney
  7818. - RULE-SET,proxy,全球代理
  7819. - RULE-SET,gfw,全球代理
  7820. - RULE-SET,applications,本地直连
  7821. - RULE-SET,ChinaMaxDomain,本地直连
  7822. - RULE-SET,ChinaMaxIPNoIPv6,本地直连,no-resolve
  7823. - RULE-SET,lan,本地直连,no-resolve
  7824. - GEOIP,CN,本地直连
  7825. - MATCH,漏网之鱼
  7826. EOF
  7827. }
  7828. # 随机salt
  7829. initRandomSalt() {
  7830. local chars="abcdefghijklmnopqrtuxyz"
  7831. local initCustomPath=
  7832. for i in {1..10}; do
  7833. echo "${i}" >/dev/null
  7834. initCustomPath+="${chars:RANDOM%${#chars}:1}"
  7835. done
  7836. echo "${initCustomPath}"
  7837. }
  7838. # 订阅
  7839. subscribe() {
  7840. readInstallProtocolType
  7841. installSubscribe
  7842. readNginxSubscribe
  7843. local renewSalt=$1
  7844. local showStatus=$2
  7845. if [[ "${coreInstallType}" == "1" || "${coreInstallType}" == "2" ]]; then
  7846. echoContent skyBlue "-------------------------备注---------------------------------"
  7847. echoContent yellow "# 查看订阅会重新生成本地账号的订阅"
  7848. echoContent red "# 需要手动输入md5加密的salt值,如果不了解使用随机即可"
  7849. echoContent yellow "# 不影响已添加的远程订阅的内容\n"
  7850. if [[ -f "/etc/v2ray-agent/subscribe_local/subscribeSalt" && -n $(cat "/etc/v2ray-agent/subscribe_local/subscribeSalt") ]]; then
  7851. if [[ -z "${renewSalt}" ]]; then
  7852. read -r -p "读取到上次安装设置的Salt,是否使用上次生成的Salt ?[y/n]:" historySaltStatus
  7853. if [[ "${historySaltStatus}" == "y" ]]; then
  7854. subscribeSalt=$(cat /etc/v2ray-agent/subscribe_local/subscribeSalt)
  7855. else
  7856. read -r -p "请输入salt值, [回车]使用随机:" subscribeSalt
  7857. fi
  7858. else
  7859. subscribeSalt=$(cat /etc/v2ray-agent/subscribe_local/subscribeSalt)
  7860. fi
  7861. else
  7862. read -r -p "请输入salt值, [回车]使用随机:" subscribeSalt
  7863. showStatus=
  7864. fi
  7865. if [[ -z "${subscribeSalt}" ]]; then
  7866. subscribeSalt=$(initRandomSalt)
  7867. fi
  7868. echoContent yellow "\n ---> Salt: ${subscribeSalt}"
  7869. echo "${subscribeSalt}" >/etc/v2ray-agent/subscribe_local/subscribeSalt
  7870. rm -rf /etc/v2ray-agent/subscribe/default/*
  7871. rm -rf /etc/v2ray-agent/subscribe/clashMeta/*
  7872. rm -rf /etc/v2ray-agent/subscribe_local/default/*
  7873. rm -rf /etc/v2ray-agent/subscribe_local/clashMeta/*
  7874. rm -rf /etc/v2ray-agent/subscribe_local/sing-box/*
  7875. showAccounts >/dev/null
  7876. if [[ -n $(ls /etc/v2ray-agent/subscribe_local/default/) ]]; then
  7877. if [[ -f "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" && -n $(cat "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl") ]]; then
  7878. if [[ -z "${renewSalt}" ]]; then
  7879. read -r -p "读取到其他订阅,是否更新?[y/n]" updateOtherSubscribeStatus
  7880. else
  7881. updateOtherSubscribeStatus=y
  7882. fi
  7883. fi
  7884. local subscribePortLocal="${subscribePort}"
  7885. find /etc/v2ray-agent/subscribe_local/default/* | while read -r email; do
  7886. email=$(echo "${email}" | awk -F "[d][e][f][a][u][l][t][/]" '{print $2}')
  7887. local emailMd5=
  7888. emailMd5=$(echo -n "${email}${subscribeSalt}"$'\n' | md5sum | awk '{print $1}')
  7889. cat "/etc/v2ray-agent/subscribe_local/default/${email}" >>"/etc/v2ray-agent/subscribe/default/${emailMd5}"
  7890. if [[ "${updateOtherSubscribeStatus}" == "y" ]]; then
  7891. updateRemoteSubscribe "${emailMd5}" "${email}"
  7892. fi
  7893. local base64Result
  7894. base64Result=$(base64 -w 0 "/etc/v2ray-agent/subscribe/default/${emailMd5}")
  7895. echo "${base64Result}" >"/etc/v2ray-agent/subscribe/default/${emailMd5}"
  7896. echoContent yellow "--------------------------------------------------------------"
  7897. local currentDomain=${currentHost}
  7898. if [[ -n "${currentDefaultPort}" && "${currentDefaultPort}" != "443" ]]; then
  7899. currentDomain="${currentHost}:${currentDefaultPort}"
  7900. fi
  7901. if [[ -n "${subscribePortLocal}" ]]; then
  7902. if [[ "${subscribeType}" == "http" ]]; then
  7903. currentDomain="$(getPublicIP):${subscribePort}"
  7904. else
  7905. currentDomain="${currentHost}:${subscribePort}"
  7906. fi
  7907. fi
  7908. if [[ -z "${showStatus}" ]]; then
  7909. echoContent skyBlue "\n----------默认订阅----------\n"
  7910. echoContent green "email:${email}\n"
  7911. echoContent yellow "url:${subscribeType}://${currentDomain}/s/default/${emailMd5}\n"
  7912. echoContent yellow "在线二维码:https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=${subscribeType}://${currentDomain}/s/default/${emailMd5}\n"
  7913. if [[ "${release}" != "alpine" ]]; then
  7914. echo "${subscribeType}://${currentDomain}/s/default/${emailMd5}" | qrencode -s 10 -m 1 -t UTF8
  7915. fi
  7916. # clashMeta
  7917. if [[ -f "/etc/v2ray-agent/subscribe_local/clashMeta/${email}" ]]; then
  7918. cat "/etc/v2ray-agent/subscribe_local/clashMeta/${email}" >>"/etc/v2ray-agent/subscribe/clashMeta/${emailMd5}"
  7919. sed -i '1i\proxies:' "/etc/v2ray-agent/subscribe/clashMeta/${emailMd5}"
  7920. local clashProxyUrl="${subscribeType}://${currentDomain}/s/clashMeta/${emailMd5}"
  7921. clashMetaConfig "${clashProxyUrl}" "${emailMd5}"
  7922. echoContent skyBlue "\n----------clashMeta订阅----------\n"
  7923. echoContent yellow "url:${subscribeType}://${currentDomain}/s/clashMetaProfiles/${emailMd5}\n"
  7924. echoContent yellow "在线二维码:https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=${subscribeType}://${currentDomain}/s/clashMetaProfiles/${emailMd5}\n"
  7925. if [[ "${release}" != "alpine" ]]; then
  7926. echo "${subscribeType}://${currentDomain}/s/clashMetaProfiles/${emailMd5}" | qrencode -s 10 -m 1 -t UTF8
  7927. fi
  7928. fi
  7929. # sing-box
  7930. if [[ -f "/etc/v2ray-agent/subscribe_local/sing-box/${email}" ]]; then
  7931. cp "/etc/v2ray-agent/subscribe_local/sing-box/${email}" "/etc/v2ray-agent/subscribe/sing-box_profiles/${emailMd5}"
  7932. echoContent skyBlue " ---> 下载 sing-box 通用配置文件"
  7933. if [[ "${release}" == "alpine" ]]; then
  7934. wget -O "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" -q "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/documents/sing-box.json"
  7935. else
  7936. wget -O "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" -q "${wgetShowProgressStatus}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/documents/sing-box.json"
  7937. fi
  7938. jq ".outbounds=$(jq ".outbounds|map(if has(\"outbounds\") then .outbounds += $(jq ".|map(.tag)" "/etc/v2ray-agent/subscribe_local/sing-box/${email}") else . end)" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}")" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" >"/etc/v2ray-agent/subscribe/sing-box/${emailMd5}_tmp" && mv "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}_tmp" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}"
  7939. jq ".outbounds += $(jq '.' "/etc/v2ray-agent/subscribe_local/sing-box/${email}")" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" >"/etc/v2ray-agent/subscribe/sing-box/${emailMd5}_tmp" && mv "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}_tmp" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}"
  7940. echoContent skyBlue "\n----------sing-box订阅----------\n"
  7941. echoContent yellow "url:${subscribeType}://${currentDomain}/s/sing-box/${emailMd5}\n"
  7942. echoContent yellow "在线二维码:https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=${subscribeType}://${currentDomain}/s/sing-box/${emailMd5}\n"
  7943. if [[ "${release}" != "alpine" ]]; then
  7944. echo "${subscribeType}://${currentDomain}/s/sing-box/${emailMd5}" | qrencode -s 10 -m 1 -t UTF8
  7945. fi
  7946. fi
  7947. echoContent skyBlue "--------------------------------------------------------------"
  7948. else
  7949. echoContent green " ---> email:${email},订阅已更新,请使用客户端重新拉取"
  7950. fi
  7951. done
  7952. fi
  7953. else
  7954. echoContent red " ---> 未安装伪装站点,无法使用订阅服务"
  7955. fi
  7956. }
  7957. # 更新远程订阅
  7958. updateRemoteSubscribe() {
  7959. local emailMD5=$1
  7960. local email=$2
  7961. while read -r line; do
  7962. local subscribeType=
  7963. subscribeType="https"
  7964. local serverAlias=
  7965. serverAlias=$(echo "${line}" | awk -F "[:]" '{print $3}')
  7966. local remoteUrl=
  7967. remoteUrl=$(echo "${line}" | awk -F "[:]" '{print $1":"$2}')
  7968. local subscribeTypeRemote=
  7969. subscribeTypeRemote=$(echo "${line}" | awk -F "[:]" '{print $4}')
  7970. if [[ -n "${subscribeTypeRemote}" ]]; then
  7971. subscribeType="${subscribeTypeRemote}"
  7972. fi
  7973. local clashMetaProxies=
  7974. clashMetaProxies=$(curl -s "${subscribeType}://${remoteUrl}/s/clashMeta/${emailMD5}" | sed '/proxies:/d' | sed "s/\"${email}/\"${email}_${serverAlias}/g")
  7975. if ! echo "${clashMetaProxies}" | grep -q "nginx" && [[ -n "${clashMetaProxies}" ]]; then
  7976. echo "${clashMetaProxies}" >>"/etc/v2ray-agent/subscribe/clashMeta/${emailMD5}"
  7977. echoContent green " ---> clashMeta订阅 ${remoteUrl}:${email} 更新成功"
  7978. else
  7979. echoContent red " ---> clashMeta订阅 ${remoteUrl}:${email}不存在"
  7980. fi
  7981. local default=
  7982. default=$(curl -s "${subscribeType}://${remoteUrl}/s/default/${emailMD5}")
  7983. if ! echo "${default}" | grep -q "nginx" && [[ -n "${default}" ]]; then
  7984. default=$(echo "${default}" | base64 -d | sed "s/#${email}/#${email}_${serverAlias}/g")
  7985. echo "${default}" >>"/etc/v2ray-agent/subscribe/default/${emailMD5}"
  7986. echoContent green " ---> 通用订阅 ${remoteUrl}:${email} 更新成功"
  7987. else
  7988. echoContent red " ---> 通用订阅 ${remoteUrl}:${email} 不存在"
  7989. fi
  7990. local singBoxSubscribe=
  7991. singBoxSubscribe=$(curl -s "${subscribeType}://${remoteUrl}/s/sing-box_profiles/${emailMD5}")
  7992. if ! echo "${singBoxSubscribe}" | grep -q "nginx" && [[ -n "${singBoxSubscribe}" ]]; then
  7993. singBoxSubscribe=${singBoxSubscribe//tag\": \"${email}/tag\": \"${email}_${serverAlias}}
  7994. singBoxSubscribe=$(jq ". +=${singBoxSubscribe}" "/etc/v2ray-agent/subscribe_local/sing-box/${email}")
  7995. echo "${singBoxSubscribe}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${email}"
  7996. echoContent green " ---> 通用订阅 ${remoteUrl}:${email} 更新成功"
  7997. else
  7998. echoContent red " ---> 通用订阅 ${remoteUrl}:${email} 不存在"
  7999. fi
  8000. done < <(grep -v '^$' <"/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl")
  8001. }
  8002. # 切换alpn
  8003. switchAlpn() {
  8004. echoContent skyBlue "\n功能 1/${totalProgress} : 切换alpn"
  8005. if [[ -z ${currentAlpn} ]]; then
  8006. echoContent red " ---> 无法读取alpn,请检查是否安装"
  8007. exit 0
  8008. fi
  8009. echoContent red "\n=============================================================="
  8010. echoContent green "当前alpn首位为:${currentAlpn}"
  8011. echoContent yellow " 1.当http/1.1首位时,trojan可用,gRPC部分客户端可用【客户端支持手动选择alpn的可用】"
  8012. echoContent yellow " 2.当h2首位时,gRPC可用,trojan部分客户端可用【客户端支持手动选择alpn的可用】"
  8013. echoContent yellow " 3.如客户端不支持手动更换alpn,建议使用此功能更改服务端alpn顺序,来使用相应的协议"
  8014. echoContent red "=============================================================="
  8015. if [[ "${currentAlpn}" == "http/1.1" ]]; then
  8016. echoContent yellow "1.切换alpn h2 首位"
  8017. elif [[ "${currentAlpn}" == "h2" ]]; then
  8018. echoContent yellow "1.切换alpn http/1.1 首位"
  8019. else
  8020. echoContent red '不符合'
  8021. fi
  8022. echoContent red "=============================================================="
  8023. read -r -p "请选择:" selectSwitchAlpnType
  8024. if [[ "${selectSwitchAlpnType}" == "1" && "${currentAlpn}" == "http/1.1" ]]; then
  8025. local frontingTypeJSON
  8026. frontingTypeJSON=$(jq -r ".inbounds[0].streamSettings.tlsSettings.alpn = [\"h2\",\"http/1.1\"]" ${configPath}${frontingType}.json)
  8027. echo "${frontingTypeJSON}" | jq . >${configPath}${frontingType}.json
  8028. elif [[ "${selectSwitchAlpnType}" == "1" && "${currentAlpn}" == "h2" ]]; then
  8029. local frontingTypeJSON
  8030. frontingTypeJSON=$(jq -r ".inbounds[0].streamSettings.tlsSettings.alpn =[\"http/1.1\",\"h2\"]" ${configPath}${frontingType}.json)
  8031. echo "${frontingTypeJSON}" | jq . >${configPath}${frontingType}.json
  8032. else
  8033. echoContent red " ---> 选择错误"
  8034. exit 0
  8035. fi
  8036. reloadCore
  8037. }
  8038. # 初始化realityKey
  8039. initRealityKey() {
  8040. echoContent skyBlue "\n生成Reality key\n"
  8041. if [[ -n "${currentRealityPublicKey}" && -z "${lastInstallationConfig}" ]]; then
  8042. read -r -p "读取到上次安装记录,是否使用上次安装时的PublicKey/PrivateKey ?[y/n]:" historyKeyStatus
  8043. if [[ "${historyKeyStatus}" == "y" ]]; then
  8044. realityPrivateKey=${currentRealityPrivateKey}
  8045. realityPublicKey=${currentRealityPublicKey}
  8046. fi
  8047. elif [[ -n "${currentRealityPublicKey}" && -n "${lastInstallationConfig}" ]]; then
  8048. realityPrivateKey=${currentRealityPrivateKey}
  8049. realityPublicKey=${currentRealityPublicKey}
  8050. fi
  8051. if [[ -z "${realityPrivateKey}" ]]; then
  8052. if [[ "${selectCoreType}" == "2" || "${coreInstallType}" == "2" ]]; then
  8053. realityX25519Key=$(/etc/v2ray-agent/sing-box/sing-box generate reality-keypair)
  8054. realityPrivateKey=$(echo "${realityX25519Key}" | head -1 | awk '{print $2}')
  8055. realityPublicKey=$(echo "${realityX25519Key}" | tail -n 1 | awk '{print $2}')
  8056. echo "publicKey:${realityPublicKey}" >/etc/v2ray-agent/sing-box/conf/config/reality_key
  8057. else
  8058. read -r -p "请输入Private Key[回车自动生成]:" historyPrivateKey
  8059. if [[ -n "${historyPrivateKey}" ]]; then
  8060. realityX25519Key=$(/etc/v2ray-agent/xray/xray x25519 -i "${historyPrivateKey}")
  8061. else
  8062. realityX25519Key=$(/etc/v2ray-agent/xray/xray x25519)
  8063. fi
  8064. realityPrivateKey=$(echo "${realityX25519Key}" | grep "PrivateKey" | awk '{print $2}')
  8065. realityPublicKey=$(echo "${realityX25519Key}" | grep "Password" | awk '{print $2}')
  8066. if [[ -z "${realityPrivateKey}" ]]; then
  8067. echoContent red "输入的Private Key不合法"
  8068. initRealityKey
  8069. else
  8070. echoContent green "\n privateKey:${realityPrivateKey}"
  8071. echoContent green "\n publicKey:${realityPublicKey}"
  8072. fi
  8073. fi
  8074. fi
  8075. }
  8076. # 初始化 mldsa65Seed
  8077. initRealityMldsa65() {
  8078. echoContent skyBlue "\n生成Reality mldsa65\n"
  8079. if /etc/v2ray-agent/xray/xray tls ping "${realityServerName}:${realityDomainPort}" 2>/dev/null | grep -q "X25519MLKEM768"; then
  8080. length=$(/etc/v2ray-agent/xray/xray tls ping "${realityServerName}:${realityDomainPort}" | grep "Certificate chain's total length:" | awk '{print $5}' | head -1)
  8081. if [ "$length" -gt 3500 ]; then
  8082. if [[ -n "${currentRealityMldsa65}" && -z "${lastInstallationConfig}" ]]; then
  8083. read -r -p "读取到上次安装记录,是否使用上次安装时的Seed/Verify ?[y/n]:" historyMldsa65Status
  8084. if [[ "${historyMldsa65Status}" == "y" ]]; then
  8085. realityMldsa65Seed=${currentRealityMldsa65Seed}
  8086. realityMldsa65Verify=${currentRealityMldsa65Verify}
  8087. fi
  8088. elif [[ -n "${currentRealityMldsa65Seed}" && -n "${lastInstallationConfig}" ]]; then
  8089. realityMldsa65Seed=${currentRealityMldsa65Seed}
  8090. realityMldsa65Verify=${currentRealityMldsa65Verify}
  8091. fi
  8092. if [[ -z "${realityMldsa65Seed}" ]]; then
  8093. # if [[ "${selectCoreType}" == "2" || "${coreInstallType}" == "2" ]]; then
  8094. # realityX25519Key=$(/etc/v2ray-agent/sing-box/sing-box generate reality-keypair)
  8095. # realityPrivateKey=$(echo "${realityX25519Key}" | head -1 | awk '{print $2}')
  8096. # realityPublicKey=$(echo "${realityX25519Key}" | tail -n 1 | awk '{print $2}')
  8097. # echo "publicKey:${realityPublicKey}" >/etc/v2ray-agent/sing-box/conf/config/reality_key
  8098. # else
  8099. realityMldsa65=$(/etc/v2ray-agent/xray/xray mldsa65)
  8100. realityMldsa65Seed=$(echo "${realityMldsa65}" | head -1 | awk '{print $2}')
  8101. realityMldsa65Verify=$(echo "${realityMldsa65}" | tail -n 1 | awk '{print $2}')
  8102. # fi
  8103. fi
  8104. # echoContent green "\n Seed:${realityMldsa65Seed}"
  8105. # echoContent green "\n Verify:${realityMldsa65Verify}"
  8106. else
  8107. echoContent green " 目标域名支持X25519MLKEM768,但是证书的长度不足,忽略ML-DSA-65。"
  8108. fi
  8109. else
  8110. echoContent green " 目标域名不支持X25519MLKEM768,忽略ML-DSA-65。"
  8111. fi
  8112. }
  8113. # 检查reality域名是否符合
  8114. checkRealityDest() {
  8115. local traceResult=
  8116. traceResult=$(curl -s "https://$(echo "${realityDestDomain}" | cut -d ':' -f 1)/cdn-cgi/trace" | grep "visit_scheme=https")
  8117. if [[ -n "${traceResult}" ]]; then
  8118. echoContent red "\n ---> 检测到使用的域名,托管在cloudflare并开启了代理,使用此类型域名可能导致VPS流量被其他人使用[不建议使用]\n"
  8119. read -r -p "是否继续 ?[y/n]" setRealityDestStatus
  8120. if [[ "${setRealityDestStatus}" != 'y' ]]; then
  8121. exit 0
  8122. fi
  8123. echoContent yellow "\n ---> 忽略风险,继续使用"
  8124. fi
  8125. }
  8126. # 初始化客户端可用的ServersName
  8127. initRealityClientServersName() {
  8128. local realityDestDomainList="gateway.icloud.com,itunes.apple.com,swdist.apple.com,swcdn.apple.com,updates.cdn-apple.com,mensura.cdn-apple.com,osxapps.itunes.apple.com,aod.itunes.apple.com,download-installer.cdn.mozilla.net,addons.mozilla.org,s0.awsstatic.com,d1.awsstatic.com,images-na.ssl-images-amazon.com,m.media-amazon.com,player.live-video.net,one-piece.com,lol.secure.dyn.riotcdn.net,www.lovelive-anime.jp,www.swift.com,academy.nvidia.com,www.cisco.com,www.asus.com,www.samsung.com,www.amd.com,cdn-dynmedia-1.microsoft.com,software.download.prss.microsoft.com,dl.google.com,www.google-analytics.com"
  8129. if [[ -n "${realityServerName}" && -z "${lastInstallationConfig}" ]]; then
  8130. if echo ${realityDestDomainList} | grep -q "${realityServerName}"; then
  8131. read -r -p "读取到上次安装设置的Reality域名,是否使用?[y/n]:" realityServerNameStatus
  8132. if [[ "${realityServerNameStatus}" != "y" ]]; then
  8133. realityServerName=
  8134. realityDomainPort=
  8135. fi
  8136. else
  8137. realityServerName=
  8138. realityDomainPort=
  8139. fi
  8140. elif [[ -n "${realityServerName}" && -z "${lastInstallationConfig}" ]]; then
  8141. realityServerName=
  8142. realityDomainPort=
  8143. fi
  8144. if [[ -z "${realityServerName}" ]]; then
  8145. if [[ -n "${domain}" ]]; then
  8146. echo
  8147. read -r -p "是否使用 ${domain} 此域名作为Reality目标域名 ?[y/n]:" realityServerNameCurrentDomainStatus
  8148. if [[ "${realityServerNameCurrentDomainStatus}" == "y" ]]; then
  8149. realityServerName="${domain}"
  8150. if [[ "${selectCoreType}" == "1" ]]; then
  8151. if [[ -z "${subscribePort}" ]]; then
  8152. echo
  8153. installSubscribe
  8154. readNginxSubscribe
  8155. realityDomainPort="${subscribePort}"
  8156. else
  8157. realityDomainPort="${subscribePort}"
  8158. fi
  8159. fi
  8160. if [[ "${selectCoreType}" == "2" ]]; then
  8161. if [[ -z "${subscribePort}" ]]; then
  8162. echo
  8163. installSubscribe
  8164. readNginxSubscribe
  8165. realityDomainPort="${subscribePort}"
  8166. else
  8167. realityDomainPort="${subscribePort}"
  8168. fi
  8169. fi
  8170. fi
  8171. fi
  8172. if [[ -z "${realityServerName}" ]]; then
  8173. realityDomainPort=443
  8174. echoContent skyBlue "\n================ 配置客户端可用的serverNames ===============\n"
  8175. echoContent yellow "#注意事项"
  8176. echoContent green "Reality目标可用域名列表:https://www.v2ray-agent.com/archives/1689439383686#heading-3\n"
  8177. echoContent yellow "录入示例:addons.mozilla.org:443\n"
  8178. read -r -p "请输入目标域名,[回车]随机域名,默认端口443:" realityServerName
  8179. if [[ -z "${realityServerName}" ]]; then
  8180. randomNum=$(randomNum 1 27)
  8181. realityServerName=$(echo "${realityDestDomainList}" | awk -F ',' -v randomNum="$randomNum" '{print $randomNum}')
  8182. fi
  8183. if echo "${realityServerName}" | grep -q ":"; then
  8184. realityDomainPort=$(echo "${realityServerName}" | awk -F "[:]" '{print $2}')
  8185. realityServerName=$(echo "${realityServerName}" | awk -F "[:]" '{print $1}')
  8186. fi
  8187. fi
  8188. fi
  8189. echoContent yellow "\n ---> 客户端可用域名: ${realityServerName}:${realityDomainPort}\n"
  8190. }
  8191. # 初始化reality端口
  8192. initXrayRealityPort() {
  8193. if [[ -n "${xrayVLESSRealityPort}" && -z "${lastInstallationConfig}" ]]; then
  8194. read -r -p "读取到上次安装记录,是否使用上次安装时的端口 ?[y/n]:" historyRealityPortStatus
  8195. if [[ "${historyRealityPortStatus}" == "y" ]]; then
  8196. realityPort=${xrayVLESSRealityPort}
  8197. fi
  8198. elif [[ -n "${xrayVLESSRealityPort}" && -n "${lastInstallationConfig}" ]]; then
  8199. realityPort=${xrayVLESSRealityPort}
  8200. fi
  8201. if [[ -z "${realityPort}" ]]; then
  8202. # if [[ -n "${port}" ]]; then
  8203. # read -r -p "是否使用TLS+Vision端口 ?[y/n]:" realityPortTLSVisionStatus
  8204. # if [[ "${realityPortTLSVisionStatus}" == "y" ]]; then
  8205. # realityPort=${port}
  8206. # fi
  8207. # fi
  8208. # if [[ -z "${realityPort}" ]]; then
  8209. echoContent yellow "请输入端口[回车随机10000-30000]"
  8210. read -r -p "端口:" realityPort
  8211. if [[ -z "${realityPort}" ]]; then
  8212. realityPort=$((RANDOM % 20001 + 10000))
  8213. fi
  8214. # fi
  8215. if [[ -n "${realityPort}" && "${xrayVLESSRealityPort}" == "${realityPort}" ]]; then
  8216. handleXray stop
  8217. else
  8218. checkPort "${realityPort}"
  8219. fi
  8220. fi
  8221. if [[ -z "${realityPort}" ]]; then
  8222. initXrayRealityPort
  8223. else
  8224. allowPort "${realityPort}"
  8225. echoContent yellow "\n ---> 端口: ${realityPort}"
  8226. fi
  8227. }
  8228. # 初始化XHTTP端口
  8229. initXrayXHTTPort() {
  8230. if [[ -n "${xrayVLESSRealityXHTTPort}" && -z "${lastInstallationConfig}" ]]; then
  8231. read -r -p "读取到上次安装记录,是否使用上次安装时的端口 ?[y/n]:" historyXHTTPortStatus
  8232. if [[ "${historyXHTTPortStatus}" == "y" ]]; then
  8233. xHTTPort=${xrayVLESSRealityXHTTPort}
  8234. fi
  8235. elif [[ -n "${xrayVLESSRealityXHTTPort}" && -n "${lastInstallationConfig}" ]]; then
  8236. xHTTPort=${xrayVLESSRealityXHTTPort}
  8237. fi
  8238. if [[ -z "${xHTTPort}" ]]; then
  8239. echoContent yellow "请输入端口[回车随机10000-30000]"
  8240. read -r -p "端口:" xHTTPort
  8241. if [[ -z "${xHTTPort}" ]]; then
  8242. xHTTPort=$((RANDOM % 20001 + 10000))
  8243. fi
  8244. if [[ -n "${xHTTPort}" && "${xrayVLESSRealityXHTTPort}" == "${xHTTPort}" ]]; then
  8245. handleXray stop
  8246. else
  8247. checkPort "${xHTTPort}"
  8248. fi
  8249. fi
  8250. if [[ -z "${xHTTPort}" ]]; then
  8251. initXrayXHTTPort
  8252. else
  8253. allowPort "${xHTTPort}"
  8254. allowPort "${xHTTPort}" "udp"
  8255. echoContent yellow "\n ---> 端口: ${xHTTPort}"
  8256. fi
  8257. }
  8258. # reality管理
  8259. manageReality() {
  8260. readInstallProtocolType
  8261. readConfigHostPathUUID
  8262. readCustomPort
  8263. readSingBoxConfig
  8264. if ! echo "${currentInstallProtocolType}" | grep -q -E "7,|8," || [[ -z "${coreInstallType}" ]]; then
  8265. echoContent red "\n ---> 请先安装Reality协议,参考教程 https://www.v2ray-agent.com/archives/1680104902581#heading-11"
  8266. exit 0
  8267. fi
  8268. if [[ "${coreInstallType}" == "1" ]]; then
  8269. selectCustomInstallType=",7,"
  8270. initXrayConfig custom 1 true
  8271. elif [[ "${coreInstallType}" == "2" ]]; then
  8272. if echo "${currentInstallProtocolType}" | grep -q ",7,"; then
  8273. selectCustomInstallType=",7,"
  8274. fi
  8275. if echo "${currentInstallProtocolType}" | grep -q ",8,"; then
  8276. selectCustomInstallType="${selectCustomInstallType},8,"
  8277. fi
  8278. initSingBoxConfig custom 1 true
  8279. fi
  8280. reloadCore
  8281. subscribe false
  8282. }
  8283. # 安装reality scanner
  8284. installRealityScanner() {
  8285. if [[ ! -f "/etc/v2ray-agent/xray/reality_scan/RealiTLScanner-linux-64" ]]; then
  8286. version=$(curl -s https://api.github.com/repos/XTLS/RealiTLScanner/releases?per_page=1 | jq -r '.[]|.tag_name')
  8287. wget -c -q -P /etc/v2ray-agent/xray/reality_scan/ "https://github.com/XTLS/RealiTLScanner/releases/download/${version}/RealiTLScanner-linux-64"
  8288. chmod 655 /etc/v2ray-agent/xray/reality_scan/RealiTLScanner-linux-64
  8289. fi
  8290. }
  8291. # reality scanner
  8292. realityScanner() {
  8293. echoContent skyBlue "\n进度 1/1 : 扫描Reality域名"
  8294. echoContent red "\n=============================================================="
  8295. echoContent yellow "# 注意事项"
  8296. echoContent yellow "扫描完成后,请自行检查扫描网站结果内容是否合规,需个人承担风险"
  8297. echoContent red "某些IDC不允许扫描操作,比如搬瓦工,其中风险请自行承担\n"
  8298. echoContent yellow "1.扫描IPv4"
  8299. echoContent yellow "2.扫描IPv6"
  8300. echoContent red "=============================================================="
  8301. read -r -p "请选择:" realityScannerStatus
  8302. local type=
  8303. if [[ "${realityScannerStatus}" == "1" ]]; then
  8304. type=4
  8305. elif [[ "${realityScannerStatus}" == "2" ]]; then
  8306. type=6
  8307. fi
  8308. read -r -p "某些IDC不允许扫描操作,比如搬瓦工,其中风险请自行承担,是否继续?[y/n]:" scanStatus
  8309. if [[ "${scanStatus}" != "y" ]]; then
  8310. exit 0
  8311. fi
  8312. publicIP=$(getPublicIP "${type}")
  8313. echoContent yellow "IP:${publicIP}"
  8314. if [[ -z "${publicIP}" ]]; then
  8315. echoContent red " ---> 无法获取IP"
  8316. exit 0
  8317. fi
  8318. read -r -p "IP是否正确?[y/n]:" ipStatus
  8319. if [[ "${ipStatus}" == "y" ]]; then
  8320. echoContent yellow "结果存储在 /etc/v2ray-agent/xray/reality_scan/result.log 文件中\n"
  8321. /etc/v2ray-agent/xray/reality_scan/RealiTLScanner-linux-64 -addr "${publicIP}" | tee /etc/v2ray-agent/xray/reality_scan/result.log
  8322. else
  8323. echoContent red " ---> 无法读取正确IP"
  8324. fi
  8325. }
  8326. # hysteria管理
  8327. manageHysteria() {
  8328. echoContent skyBlue "\n进度 1/1 : Hysteria2 管理"
  8329. echoContent red "\n=============================================================="
  8330. local hysteria2Status=
  8331. if [[ -n "${singBoxConfigPath}" ]] && [[ -f "/etc/v2ray-agent/sing-box/conf/config/06_hysteria2_inbounds.json" ]]; then
  8332. echoContent yellow "依赖第三方sing-box\n"
  8333. echoContent yellow "1.重新安装"
  8334. echoContent yellow "2.卸载"
  8335. echoContent yellow "3.端口跳跃管理"
  8336. hysteria2Status=true
  8337. else
  8338. echoContent yellow "依赖sing-box内核\n"
  8339. echoContent yellow "1.安装"
  8340. fi
  8341. echoContent red "=============================================================="
  8342. read -r -p "请选择:" installHysteria2Status
  8343. if [[ "${installHysteria2Status}" == "1" ]]; then
  8344. singBoxHysteria2Install
  8345. elif [[ "${installHysteria2Status}" == "2" && "${hysteria2Status}" == "true" ]]; then
  8346. unInstallSingBox hysteria2
  8347. elif [[ "${installHysteria2Status}" == "3" && "${hysteria2Status}" == "true" ]]; then
  8348. portHoppingMenu hysteria2
  8349. fi
  8350. }
  8351. # tuic管理
  8352. manageTuic() {
  8353. echoContent skyBlue "\n进度 1/1 : Tuic管理"
  8354. echoContent red "\n=============================================================="
  8355. local tuicStatus=
  8356. if [[ -n "${singBoxConfigPath}" ]] && [[ -f "/etc/v2ray-agent/sing-box/conf/config/09_tuic_inbounds.json" ]]; then
  8357. echoContent yellow "依赖sing-box内核\n"
  8358. echoContent yellow "1.重新安装"
  8359. echoContent yellow "2.卸载"
  8360. echoContent yellow "3.端口跳跃管理"
  8361. tuicStatus=true
  8362. else
  8363. echoContent yellow "依赖sing-box内核\n"
  8364. echoContent yellow "1.安装"
  8365. fi
  8366. echoContent red "=============================================================="
  8367. read -r -p "请选择:" installTuicStatus
  8368. if [[ "${installTuicStatus}" == "1" ]]; then
  8369. singBoxTuicInstall
  8370. elif [[ "${installTuicStatus}" == "2" && "${tuicStatus}" == "true" ]]; then
  8371. unInstallSingBox tuic
  8372. elif [[ "${installTuicStatus}" == "3" && "${tuicStatus}" == "true" ]]; then
  8373. portHoppingMenu tuic
  8374. fi
  8375. }
  8376. # sing-box log日志
  8377. singBoxLog() {
  8378. cat <<EOF >/etc/v2ray-agent/sing-box/conf/config/log.json
  8379. {
  8380. "log": {
  8381. "disabled": $1,
  8382. "level": "debug",
  8383. "output": "/etc/v2ray-agent/sing-box/conf/box.log",
  8384. "timestamp": true
  8385. }
  8386. }
  8387. EOF
  8388. handleSingBox stop
  8389. handleSingBox start
  8390. }
  8391. # sing-box 版本管理
  8392. singBoxVersionManageMenu() {
  8393. echoContent skyBlue "\n进度 $1/${totalProgress} : sing-box 版本管理"
  8394. if [[ -z "${singBoxConfigPath}" ]]; then
  8395. echoContent red " ---> 没有检测到安装程序,请执行脚本安装内容"
  8396. menu
  8397. exit 0
  8398. fi
  8399. echoContent red "\n=============================================================="
  8400. echoContent yellow "1.升级 sing-box"
  8401. echoContent yellow "2.关闭 sing-box"
  8402. echoContent yellow "3.打开 sing-box"
  8403. echoContent yellow "4.重启 sing-box"
  8404. echoContent yellow "=============================================================="
  8405. local logStatus=
  8406. if [[ -n "${singBoxConfigPath}" && -f "${singBoxConfigPath}log.json" && "$(jq -r .log.disabled "${singBoxConfigPath}log.json")" == "false" ]]; then
  8407. echoContent yellow "5.关闭日志"
  8408. logStatus=true
  8409. else
  8410. echoContent yellow "5.启用日志"
  8411. logStatus=false
  8412. fi
  8413. echoContent yellow "6.查看日志"
  8414. echoContent red "=============================================================="
  8415. read -r -p "请选择:" selectSingBoxType
  8416. if [[ ! -f "${singBoxConfigPath}../box.log" ]]; then
  8417. touch "${singBoxConfigPath}../box.log" >/dev/null 2>&1
  8418. fi
  8419. if [[ "${selectSingBoxType}" == "1" ]]; then
  8420. installSingBox 1
  8421. handleSingBox stop
  8422. handleSingBox start
  8423. elif [[ "${selectSingBoxType}" == "2" ]]; then
  8424. handleSingBox stop
  8425. elif [[ "${selectSingBoxType}" == "3" ]]; then
  8426. handleSingBox start
  8427. elif [[ "${selectSingBoxType}" == "4" ]]; then
  8428. handleSingBox stop
  8429. handleSingBox start
  8430. elif [[ "${selectSingBoxType}" == "5" ]]; then
  8431. singBoxLog ${logStatus}
  8432. if [[ "${logStatus}" == "false" ]]; then
  8433. tail -f "${singBoxConfigPath}../box.log"
  8434. fi
  8435. elif [[ "${selectSingBoxType}" == "6" ]]; then
  8436. tail -f "${singBoxConfigPath}../box.log"
  8437. fi
  8438. }
  8439. # 主菜单
  8440. menu() {
  8441. cd "$HOME" || exit
  8442. echoContent red "\n=============================================================="
  8443. echoContent green "作者:mack-a"
  8444. echoContent green "当前版本:v3.4.30"
  8445. echoContent green "Github:https://github.com/mack-a/v2ray-agent"
  8446. echoContent green "描述:八合一共存脚本\c"
  8447. showInstallStatus
  8448. checkWgetShowProgress
  8449. echoContent red "\n=========================== 推广区============================"
  8450. echoContent red " "
  8451. echoContent green "VPS选购攻略:https://www.v2ray-agent.com/archives/1679975663984"
  8452. echoContent green "年付10美金低价VPS AS4837:https://www.v2ray-agent.com/archives/racknerdtao-can-zheng-li-nian-fu-10mei-yuan"
  8453. echoContent green "优质常驻套餐DMIT CN2-GIA:https://www.v2ray-agent.com/archives/186cee7b-9459-4e57-b9b2-b07a4f36931c"
  8454. echoContent green "VPS探针:https://ping.v2ray-agent.com/"
  8455. echoContent red "=============================================================="
  8456. if [[ -n "${coreInstallType}" ]]; then
  8457. echoContent yellow "1.重新安装"
  8458. else
  8459. echoContent yellow "1.安装"
  8460. fi
  8461. echoContent yellow "2.任意组合安装"
  8462. echoContent yellow "4.Hysteria2管理"
  8463. echoContent yellow "5.REALITY管理"
  8464. echoContent yellow "6.Tuic管理"
  8465. echoContent skyBlue "-------------------------工具管理-----------------------------"
  8466. echoContent yellow "7.用户管理"
  8467. echoContent yellow "8.伪装站管理"
  8468. echoContent yellow "9.证书管理"
  8469. echoContent yellow "10.CDN节点管理"
  8470. echoContent yellow "11.分流工具"
  8471. echoContent yellow "12.添加新端口"
  8472. echoContent yellow "13.BT下载管理"
  8473. echoContent yellow "15.域名黑名单"
  8474. echoContent skyBlue "-------------------------版本管理-----------------------------"
  8475. echoContent yellow "16.core管理"
  8476. echoContent yellow "17.更新脚本"
  8477. echoContent yellow "18.安装BBR、DD脚本"
  8478. echoContent skyBlue "-------------------------脚本管理-----------------------------"
  8479. echoContent yellow "20.卸载脚本"
  8480. echoContent red "=============================================================="
  8481. mkdirTools
  8482. aliasInstall
  8483. read -r -p "请选择:" selectInstallType
  8484. case ${selectInstallType} in
  8485. 1)
  8486. selectCoreInstall
  8487. ;;
  8488. 2)
  8489. selectCoreInstall
  8490. ;;
  8491. # 3)
  8492. # initXrayFrontingConfig 1
  8493. # ;;
  8494. 4)
  8495. manageHysteria
  8496. ;;
  8497. 5)
  8498. manageReality 1
  8499. ;;
  8500. 6)
  8501. manageTuic
  8502. ;;
  8503. 7)
  8504. manageAccount 1
  8505. ;;
  8506. 8)
  8507. updateNginxBlog 1
  8508. ;;
  8509. 9)
  8510. renewalTLS 1
  8511. ;;
  8512. 10)
  8513. manageCDN 1
  8514. ;;
  8515. 11)
  8516. routingToolsMenu 1
  8517. ;;
  8518. 12)
  8519. addCorePort 1
  8520. ;;
  8521. 13)
  8522. btTools 1
  8523. ;;
  8524. 14)
  8525. switchAlpn 1
  8526. ;;
  8527. 15)
  8528. blacklist 1
  8529. ;;
  8530. 16)
  8531. coreVersionManageMenu 1
  8532. ;;
  8533. 17)
  8534. updateV2RayAgent 1
  8535. ;;
  8536. 18)
  8537. bbrInstall
  8538. ;;
  8539. 20)
  8540. unInstall 1
  8541. ;;
  8542. esac
  8543. }
  8544. cronFunction
  8545. menu