Ruining the Rustock.C rumors and myths and Kaspersky Lab role

本文深入探讨了 Rustock.C 根套件的技术细节,包括其新特性、如何检测及对抗策略等。文章分析了 Rustock.C 的工作原理、内核级钩子机制,并介绍了针对该根套件的有效防御措施。
  By: HolaHola

Ruining the Rustock.C rumors and myths and Kaspersky Lab role

1. Prologue
2. Rustock new features, aggregating more information and making Detector
3. Rootkits roadmap
4. Alexander Gostev playing the RPG or the answer of the so called BIG BROTHER
5. Epilogue

1. Prologue

Rustock… The heart of evil.
Is it undetectable? Of course no. Is it possible to remove Rustock while runtime? Yes. It was rumored in 2006 as undetectable? Just for AV’s and childish rootkit detection software which were available at this time. How do we can detect it? Do we need a driver for that? OMG its hooked so many stuff in the kernel, this is tricky malware… Yes and no. Right now – right here we will build a small and easy constructible concept of the workable pure user mode detector for this “undetectable” © KL stuff.


This entire story begins in the end of 2005 year. It was absolutely clear, that modern at the end of 2005 antivirus technologies have hopelessly lagged behind from a life. More to say – rootkits quickly ruined the blind fate in Antiviruses. Hacker Defender brings a lot of new stuff to the scene and it’s started a new era in the “war” of the technologies. Well, we can’t call this war, because the both sides depends each others and can’t exists without other and most of them are double sides (what is used for hiding can be used for detection).

It is difficult to say, why AV scene long time were ignoring this entire crap and not developed a proper counteraction. It was a crisis of ideas and crisis of realization. Do you know that currently more than 70% of all computers in this world infected with something? And this number steadily grows irrespective of actions of the antivirus companies. Only one rational explanation comes to mind. They absolutely accept a state of affairs. And they basically have no anything against. It more not opposition as earlier and scales of operations now where are wider than in the ninetieth years of last century. All they want’s – your money. Do you think they really want to help somebody? Malware writers and antivirus users are almost the same in their eyes. Give them your money and shut up – that’s their main politic. It is business and no romantics here anymore.

So if THEY can’t protect or even reveal (more likely – do not want) new threats it is required to somebody replace them at the current moment of time. That’s why we all have seen an uprising of the antirootkit software during last three years. It was just a question of time – the Rustock like rootkit creation. Not being genius engineering decision trojan nevertheless has managed to become one of the most known for all history and to earn reputation of the ultimate rootkit. In the reality all Rustock series remembers us a scope of LEGO pieces collected by talented hands in one big sparkling rootkit. There is nothing extra ordinal here – it is simple professional approach to the work, the thing which is unknown for the Kaspersky Lab since its foundation and representation in 1996. Lets look what AV companies have opposed rootkits and Rustock especially and answer on the question – Why, OMG why Rustock was so undetectable all this time?

AV companies have opposed rootkits and Rustock especially the thing….
This crap called – “Proactive Defense”. It is based on well-known and vulnerable by design Host Intrusion Prevention System concepts which were presented long time ago before KL.
The main goal of this – not let the unwanted software properly work and while analyzing behavior of the program make decision about harmless it or not. What Kaspersky actually did new – its build poorly coded HIPS part inside well-known antivirus monitor and combines principles of it work with HIPS related stuff. Everything this impossible without supervision of the system. This could be done by numerous methods. By some unknown reasons authors of 99% HIPS and AV with built-in HIPS modules (called on the KL manner – “Proactive Defense”) have chosen system service descriptors tables and official weak but documented ways of system monitoring provided by NT based core such as fltfilter, notifications, configuration manager callbacks and some other stuff. Don’t believe? Lets look inside klif.sys – Kaspersky AV heart. All stuff listed below starts from DriverEntry original call and locates somewhere at 0003CXXX offset, depending on klif version.



  InitializePhase0();
  InitializeResourcesList();
  v15 = FltRegisterFilter(P, &v24, &dword_3A1A0);
  String2.Buffer = (PWSTR)v15;
  if ( v15 < 0 )
  {
    ShutdownWhileInitializationError();
    return (unsigned int)String2.Buffer;
  }
  v7 = Drink_KLINSKOE();

….stripped not interested info….

  v18 = InitializeFsFilterCommunication(&String2);
  v11 = v18;
  if ( v18 >= 0 )
  {
    v12 = CreateAndRegisterDevicesAndLinks((PDRIVER_OBJECT)P, &String2);
    if ( v12 >= 0 )
    {
      RtlInitUnicodeString((LSA_UNICODE_STRING *)&v39, &word_3C65A);
      stru_3A27C.Length = 0;
      v19 = (_WORD)String2.Length + v39 + v10->Length + 2;
      stru_3A27C.MaximumLength = (_WORD)String2.Length + v39 + v10->Length + 2;
      v13 = (WCHAR *)ExAllocatePoolWithTag(PagedPool, v19, 0x387A4C4Bu);
      stru_3A27C.Buffer = v13;
      if ( v13 )
      {

… stripped uninterested info….
            if ( v22 >= 0 )
            {
              InitializePhase1();
              Kakayata_hyinya1();
              v23 = Kakayata_hyinya2();
              HIBYTE(P->Size) = v23;
              if ( v23 )
                HIBYTE(P->Size) = sub_14F0C();
              Kakayata_hyinya3();
              if ( HIBYTE(P->Size) )
              {
                OwnAndFuckTheSystem();
                SetRegistryCallback();
                v11 = FltStartFiltering(dword_3A1A0);
                
We interested in the following entries

INIT:0003C4BD                 call    OwnAndFuckTheSystem
INIT:0003C4C2                 call    SetRegistryCallback

  v3 = PsSetCreateProcessNotifyRoutine(NotifyRoutine, 0);
  v2 = v3;
  if ( v3 >= 0 )
  {
    byte_38A76 = 1;
    v4 = PsSetCreateThreadNotifyRoutine(sub_1CE78);
    v2 = v4;
    if ( v4 >= 0 )
    {
      byte_38A77 = 1;
      v5 = PsSetLoadImageNotifyRoutine(nullsub_1);
      v2 = v5;
      if ( v5 >= 0 )
      {
        byte_38B14 = 1;
        HookSSDTEntry(&dword_38EFC, sub_1DBD6, "NtOpenProcess");
        HookSSDTEntry(&dword_39004, sub_1DAB2, "NtAdjustPrivilegesToken");
        HookSSDTEntry(&dword_39014, sub_1DC7E, "NtTerminateProcess");
        HookSSDTEntry(&dword_38EEC, sub_1DCF0, "NtWriteVirtualMemory");
        HookSSDTEntry(&dword_38F14, sub_1DDAE, "NtCreateThread");
        HookSSDTEntry(&dword_38FF8, sub_1D010, "NtSaveKey");
        HookSSDTEntry(&dword_38EE8, sub_1D320, "NtRestoreKey");
        HookSSDTEntry(&dword_38F0C, sub_1D1BE, "NtReplaceKey");
        if ( IsWindowsXP || IsWindows2000 )
        {
          HookSSDTEntry(&dword_38F10, sub_1D4EE, "NtCreateKey");
          HookSSDTEntry(&dword_38EF8, sub_1D60C, "NtSetValueKey");
          HookSSDTEntry(&dword_38EE0, sub_1D72A, "NtQueryValueKey");
          HookSSDTEntry(&dword_38F18, sub_1D82A, "NtDeleteKey");
          HookSSDTEntry(&dword_38EF4, sub_1D8EA, "NtQueryMultipleValueKey");
          HookSSDTEntry(&dword_38F04, sub_1D9C8, "NtDeleteValueKey");
        }
        GetProcedureAddressEx(&dword_38A84, "PsGetThreadId");
        GetProcedureAddressEx(&dword_38A88, "PsGetThreadProcessId");
        GetProcedureAddressEx(&dword_38A8C, "PsGetProcessId");
        if ( dword_38A84 )
        {
          if ( dword_38A88 )
          {
            HookSSDTEntry(&dword_38F08, sub_1DEAC, "NtSetContextThread");
            if ( (unsigned __int8)HookSSDTEntry(&dword_38F00, sub_2115A, "NtResumeThread") )
              HookSSDTEntry(&dword_39018, sub_21038, "NtSuspendThread");
            if ( IsWindowsXP )
            {
              if ( dword_38A8C )
                HookSSDTEntry(&dword_39010, sub_20F54, "NtSuspendProcess");
            }
          }
        }
        HookSSDTEntry(&dword_38AFC, sub_1F71E, "NtConnectPort");
        HookSSDTEntry(&dword_38B00, sub_1FEB0, "NtRequestWaitReplyPort");
        HookSSDTEntry(&dword_38AF8, sub_1F5EE, "NtSecureConnectPort");
        HookSSDTEntry(&dword_38AE0, sub_1EFC6, "NtOpenFile");
        HookSSDTEntry(&dword_38AE4, sub_1F16A, "NtCreateFile");
        HookSSDTEntry(&dword_38AE8, sub_1F32C, "NtFsControlFile");
        HookSSDTEntry(&dword_38AEC, sub_1F438, "NtDeviceIoControlFile");
        dword_38A98 = SpecialHookSSDTEntry("NtQueryInformationThread");
        if ( IsWindowsXP || IsWindows2003 )
        {
          if ( dword_3A264 & 0x40 )
            sub_31978();
        }
        HookSSDTEntry(&dword_38FFC, sub_20936, "NtSystemDebugControl");
        HookSSDTEntry(&dword_3900C, sub_209C4, "NtLoadDriver");
        HookSSDTEntry(&dword_38FA0, sub_20A8C, "NtSetSecurityObject");
        HookSSDTEntry(&dword_38A94, sub_1DF84, "NtClose");
        HookSSDTEntry(&dword_39000, sub_20E52, "NtCreateSymbolicLinkObject");
        HookSSDTEntry(&dword_38FB0, sub_20EA6, "NtSetSystemInformation");
        HookSSDTEntry(&dword_38EF0, sub_20E7C, "NtOpenSection");
        if ( dword_38A88 )
        {
          if ( dword_38A84 )
            HookSSDTEntry(&dword_39008, sub_20BFA, "NtQueueApcThread");
        }
        HookSSDTEntry(&dword_38EE4, sub_2127C, "NtDuplicateObject");
      }
    }
  }
  Zamuta_c_CSRSS_chto_prosto_pizdec_delat_nehuy_bulo_vidat_ili_deti_dorvalis_do_ddk();
  return v2;
}



So as you see modern Antiviruses uses SSDT hooking and a lot of other idiocy. Does it help? No of course, because:

HIPS concept vulnerable at the many points. First – it is impossible to do something if this something already installed in the system at kernel level, so it’s become useless against active rootkits. Second – any proactive defense requires heavy support of user and in the end only one wrong user decision can compromise this entire hooking circus. Third – it is always will be the way to compromise them, because they are not a part of operation system. They are the same intruders just acting like the same rootkits and owning your system more then some malware can. That’s why most of antimalware vendors were scared by Vista changes. These changes forced them to scream because Microsoft just in one shot dropped all this garbage – antimalware and trojans hookers.

Fourth – any Proactive Defense KILLS performance, just because – more operations required and slightly more were processing occurring. Looking on extremely buggy soft from AV companies do you think the handlers of their hooks are the beauty or the world-class programmed? But if you have a lot of CPU and RAM – well you need all this for something yeah? For AV ;-)

Notification callbacks used by most of the widely spread antimalware solutions (some of them using just only them and nothing more) also vulnerable. Malware can do the drop in the few steps (this is called “cascade”) and remove notifications as well or patch them, or call them or patch their real handlers in the antivirus drivers. It is absolutely nonsense to believe in power of notifies only. Configuration manager callbacks can be fooled at the same point, more to say, they mostly used by malware not by legitimate software. Well this is changed in the Vista.
Do you believe in flt filters? Keep thinking so. There are exists fully workable file system parsers in both user / kernel mode, including fsd requests emulators.

2. Rustock new features, aggregating more information

We did not wish to go into details, but as now the information has poured down literally river and mostly not from the antivirus companies we have decided to add and collect together all new stuff about rootkit.

On Uni CPU systems Rustock behavior differs from Multi CPU.
It setups more hooks inside tcpip.sys in the following manner. There are many internal tcpip.sys
call looking like that

call [F6633220] (example)

replaced on

call [83882200] (example)


Rustock patches these instructions on the following way - instead tcpip.sys address it places rootkit handler address. This is not a pure inline hook, but address change hook. This is definitely good idea, because this is just 4 byte change and most of antirootkit can fails to trace such modification due to realization specific. They were starting analyzing from the beginning of modification and translating address as an instruction which results in skipping these hooks.
We must admit that we are speaking about nonpacked victim drivers.

The detection of these hooks.

One of the ways to detect such kind of tricky modification – build a map of points from which we will start real-time disassembling and analyzing, because static analysis is shit by current problem determination. So we going to be some kind of IDA Where we can get these points to disassemble? Answer is simple. Firstly it is entry point of driver. Second it will be the Export table. We can also reach original IRP handlers from the entry point of driver (they are mostly assigned here). We can use even the Import table and find all references to functions in the code. And the ultimate but not very easy to implement method – search for calls inside code and analyze jumps of all kind. After building the map we will trace the code as we usually do, and when the mismatch with the original code will be found – we will search for the nearest map point and start disassembling routine which will dynamically analyze code and trace the hook, because authors of rootkits can do “tandem” of jumps, calls and other stuff inside victim driver. Theoretically we can even find the hidden kernel mode shit by tracing hooks, but it is not required – all what we need find hooks. The important one thing – we should obtain original files to be able do unhook. The best way will be have a database of system components, but this database will be huge and operation system dependent, so we can simple read original content from the our low level IO dispatch driver which will not use windows API nor FS drivers queue at all. But this will give us a lot of compatibility problems on the different machines and with dynamic disks. The extreme way implemented for example in private antirootkit called “Resurrector”– analyze hooks and find the real handlers inside them.

Rustock also may hook pIofCallDriver on the same manner and sets two IAT interceptors on wanarp.sys - NdisOpenAdapter/NdisCloseAdapter similar to Rustock.B hooks. To bypass IofCallDriver hook use the own self made alternative.

IofCallDriver(
    IN PDEVICE_OBJECT  DeviceObject,
    IN OUT PIRP  Irp
    )
{    
//….variables stack location checking etc – use your brains
//….Blah blah blah blah ….

Proc1 = (PHANDLER_PROC)DeviceObject->DriverObject->MajorFunction[v3->MajorFunction];
return Proc1(DeviceObject, Irp);
}


Rustock also hooks several IDT entries except KiSystemService, but this was acknowledged not everywhere, well actually we didn’t fully check this part.

Looks this pe386 release buggy as the previous Rustock.B which behavior also was a puzzle depending on the different hardware configurations. It filters FSD requests to the ntfs.sys, fastfat.sys with help of the inline hooks (listed in previous article), and pIofCallDriver.
But here is the bug. On our Uni CPU system it doesn't filters some information, so we are getting equal file size in raw mode and through API enumeration. crazy isn't it? If you will call GetFileSize to the null.sys (infected driver) it will report the faked filesize. If you will call NtQueryInformationFile with FILE_STANDARD_INFORMATION the EndOfFile field of the structure will report you faked filesize, but the AllocationSize field will give you the real infected file size.

On the FAT32 systems, Rustock filtering more effective, GMER v1.14 can't see any hooks - because it loads faked images from disk. But our experiments with file request showed the abnormal filter behavior - it returns AllocationSize = INFINITE value or 0. So due to crazy nature of this spambot we can conclude - it is necessary to create a special procedure to check files inside drivers directory, because retrieving size of all volume files with a different checks will dramatically decrease performance and increase false positives count of the detector.
You can detect mismatch of file size even from user mode, as described above Cool?

Rustock hides two threads inside winlogon.exe and 4 handles of them 2 in the same winlogon process and 2 inside csrss.exe with the help of NtQuerySystemInformation filtering.

It is very easy to bypass a KiSystemService hook which is the one of main stealth parts of this version. As you probably know all kernel mode Zw* functions going to the stub similar to user mode which in the end calls KiSystemService and inside it calls real service function. Here the example of ZwQueryKey stub in kernel.


.text:0042997C ; NTSTATUS __stdcall ZwQueryKey(HANDLE KeyHandle, KEY_INFORMATION_CLASS KeyInformationClass, PVOID KeyInformation, ULONG KeyInformationLength, PULONG ResultLength)
.text:0042997C                 public ZwQueryKey
.text:0042997C ZwQueryKey      proc near               ; CODE XREF: sub_4A5CFC+13 p
.text:0042997C                                         ; sub_4A5CFC+51p ...
.text:0042997C
.text:0042997C KeyHandle       = dword ptr  4
.text:0042997C KeyInformationClass= dword ptr  8
.text:0042997C KeyInformation  = dword ptr  0Ch
.text:0042997C KeyInformationLength= dword ptr  10h
.text:0042997C ResultLength    = dword ptr  14h
.text:0042997C
.text:0042997C                 mov     eax, 0A0h
.text:00429981                 lea     edx, [esp+KeyHandle]
.text:00429985                 pushf
.text:00429986                 push    8
.text:00429988                 call    KiSystemService
.text:0042998D                 retn    14h
.text:0042998D ZwQueryKey      endp


So Rustock can filter both Nt from user mode and Zw from kernel mode requests, because of KiSystemService hook. To bypass this it is necessary to load clean ntoskrnl image from disk, but do this in raw mode to not reproduce Gmerek mistake, reconfigure it and use original functions. The same can be used to bypass all HIPS hooks and other kernel mode hooking shit. The extreme way here – reassign your code on the new loaded core by patching addresses of calls. This would require a lot of work, but this is possible, we tried =) Check 90210 article first for more info for the beginning. By the way the same can be used and in the different way to compromise detection.

Heh! Right now after all this we can find all it hooks (don’t think push/retf is the something extra ordinal hard to detect), find an infected file and do this in the user mode (with a proper FS parser user mode realization)! We can build a workable pure user mode detector capable to find rootkit hooks, rootkit infected file and even (if we implement tracer) kernel mode addresses belongs to the rootkit body Of course we need NTFS/FAT32 parsers. But that is cool! It is possible to do even on Visual Basic!

The famous protector on the Rustock.C

Yeah it was cool! Especially hardware bind part and kernel mode antidebuggers trick with DR registers. But fortunately not everything is impossible and more to say author of this rootkit has helped us a lot by giving such wonderful target of the investigation as his rootkits. Thanks!

It uses hardware based keys generation with help of PCI-to-ISA bridge ;-)
We were lazy. It is 3 combined DWORD from different unique hashes representing a 79228162514264337593543950336 combinations encryption key Do you wanna to brute it? You can read excellent article from ThreatExpert and found some more interesting data.

KL spawned another myth in their not so long time ago published article. The myth about rootkit lifetime.

Well, KL employees, do some STFG before posting such nonsense in your favorite manner.
The dropper of this cool shit was firstly highlighted here
http://www.castlecops.com/p950279-daily_catch_june_06.html

In the June of 2007, exactly in the same time when it was accidentally revealed in the wild by group of the independent researchers. So probably creation time of this – the beginning of the 2007, because such work can’t be done in two-three months LOL, maybe your klif.sys was coded in 2-3 month and because of this it is so buggy?

At this point we will suggest KL employees and PR writers drink some poison and kill themselves up the wall with a good speed Do this world a little better guys and girls.

3. Rootkit roadmap.

What will be in near future? Rustock.D? Is it exists? What is can include?

What a hell a lot of questions Actually we don’t know about Rustock.D and to be honest absolutely don’t care about it. We know one thing, which mister Gostev from KL definitely do not know or do not want to agree by posting a lot of shit on a site where he is lurking.

THERE ARE NO UNDETECTABLE ROOTKITS AND NO ABSOLUTE DETECTORS.
This term was posted exactly in the end of 2006 which is pointed as a time of Rustock.C promo campaign start time.

And THERE ARE NO GOOD AV’s, there are no antivirus echelon’s – all them weak.

The best way for users – stop believing in fairy tales from AV companies such as KL and start thinking by their head’s. Are you not agreeing? Then together find a wall with KL collective.

We believe that current level of Win32 security is out-of-dated at the level of the principles not implementation. AV companies mostly thinking by criteria’s and ideas which have become outdated with rootkits rising. We do not like malware, but the same we do not like shitty antimalware from highly paid script-kiddies.

Rustock.C can be ported to Win64 without a doubt. No, PageGuard will not help. No UAC will not help – most of users simple irritated by it never endless popups. Just remember – you already have everything in the NTOS that can be used against ALL modern malware. Use your brains and hands.

Inline hooks have practically settled themselves and we believe in their dead in future. Well in the meaning of the current level and implementation. Bootkits? Bad idea from the origin, we always will know what we should check and how to do that. Bioskits? Hah, well try, but this will be a combine type bioskit-rootkit, and rootkit part will be always detectable. Blue Pill? Not in this life, but everything is possible, actually we do not believe in Matrix Hiding data from raw reading? Yeah – always unstable realization and easy to detect by third-party things. Hiding sectors? Encryption of data? Detectable via execution profiling. And all detectable via offline analysis. So maybe viruses? Yes. The future is for viruses. Trojans must die by origin. Stop earning money dear script-kiddies, find a normal job =) And stop calling everything 0day. This 0day can’t be 0day be determination, since all what you doing – using the well-known internal NT specifics maybe even in perverted way.

4. Alexander Gostev playing the RPG or the answer of the so called BIG BROTHER

They waited long time. Almost one month was required to the Kaspersky Laboratory to strike back. Well they can’t just shut up and stay away from this. Money rules the world and minds. Of course, this is the best way to do the more advertisement of their products. Even if this is the pure bullshit and nonsense. Well, they don’t doing this in the first time, so here the wonderful article from well-known technically low-professionals from Kaspersky Lab. Here is the infamous article with a lot of grammatical, technical, and common sense errors (yeah you can point on this crazy and poor English, but it is not native language instead of language of the authors of this article) http://www.viruslist.com/ru/analysis?pubid=204007614

After publishing this plagiarism and rumoring the date of the Rustock.C creation to the end of the 2007 Kaspersky Laboratory started doing the same things as it usually loves to do – search enemies outside. Before searching somebody outside dear KL employees it is required to search the same shit inside yourself and your company which always was a primary target of the sneers and attacks owing to the disgusting actions and behavior with everybody outside KL. Do you think you Gods? Or maybe “Elita nax”? No you just a pathetic scope of former carders, “hackers” and “crackers” with extremely aggressive and blind promotional politics. Keep trying – heck the ploned.

5. Epilogue.

We just are awaiting mister A. Gostev in “gosti” to speak about Rustock.C, spam sending malware, an insiders who are uploading the internal data to the same shitmakers from outside for a long time and speak about his love to play in the Role Playing Games (WOW?). We just awaiting you Alexander (by the way you are namesake of one of us ), please feel free to contact - > Send a Memo to us through this site and we will give you coordinates in the Germany and further information where we can meet and discuss all this. We are promising – no offense and other bullshit from our side Are you man mister Gostev? Or all what you can do – speak bullshit, threats to us, splash a lot of saliva - do this on yours company owned site and sponsor the ridiculous articles from your PR first lady?

HolaHola aka DNY / VX Heavens
EP_X0FF / VX Heavens
Labourge / VX Heavens
AntiEXE / VX Heavens
And vse-vse-vse ;-)

08.06.2008

<think>嗯,用户遇到了Docker报错"Error response from daemon: Container xxx is not running",这确实是个常见问题。从用户提供的引用内容看,ta应该已经查阅过相关资料,但可能需要更系统的解决方案。 用户可能是个刚接触Docker的开发者,正尝试操作容器时遇到阻碍。这个错误表面意思是容器未运行,但背后可能有多种原因:容器从未启动过、已停止运行、启动后立即退出等。用户最迫切需要的应该是清晰的排查步骤。 让我梳理几个关键点:首先需要区分容器状态,通过docker ps -a查看STATUS字段很重要。如果是Exited状态,要检查日志;如果是Created状态,说明从未启动。其次要关注端口冲突问题,这在引用[2]中提到了端口映射异常的情况。最后是启动策略,对于数据库类容器需要保持前台运行。 考虑到用户可能不熟悉命令行,准备在回复时加入具体命令示例,比如docker logs查看日志、docker inspect分析配置。对于自启动容器的情况,要特别说明--restart参数的用法。 用户似乎更关注解决方案而非理论,所以回复会以实操步骤为主。但也要解释常见原因,比如容器启动后立即退出的情况,这通常和进程结束有关。对于redis/mysql这类服务,必须强调保持前台进程的必要性。 在相关问题上,准备设计几个延伸方向:如何避免重复报错、容器状态管理技巧、服务类容器的特殊处理等。用户如果解决当前问题后,可能会需要这些进阶知识。</think>遇到 `Error response from daemon: Container xxx is not running` 错误时,说明你尝试操作的容器(`xxx` 是容器名或 ID)**当前未运行**。以下是系统化的解决步骤: --- ### **1. 确认容器状态** ```bash docker ps -a | grep "xxx" # 替换 xxx 为你的容器名或 ID ``` * **若 STATUS 显示 `Exited`**:容器已停止(下一步排查原因)。 * **若 STATUS 显示 `Created`**:容器从未启动过(跳至步骤 3)。 * **若未找到容器**:容器不存在(需重新创建或检查名称拼写)。 --- ### **2. 排查容器停止的原因(针对 `Exited` 状态)** #### **a. 查看停止日志** ```bash docker logs xxx # 显示容器上次运行时的输出日志 ``` * **关键线索**:日志末尾的错误信息(如端口冲突、配置文件错误、依赖服务未启动等)。 * **常见问题**: * **端口冲突**:`Bind for 0.0.0.0:8080 failed: port is already allocated` 解决方案:更换端口或停止占用端口的进程。 * **配置文件错误**:如 Redis 的 `redis.conf` 语法错误、MySQL 的 `my.cnf` 配置错误。 解决方案:修正配置文件后重启容器。 * **依赖未就绪**:如数据库容器启动时连接的后端服务不可用。 解决方案:确保依赖服务先启动,或为容器添加重试机制(如 `--health-cmd`)。 #### **b. 检查容器退出码** ```bash docker inspect xxx --format='{{.State.ExitCode}}' # 查看退出状态码 ``` * **`0`**:正常退出(可能是任务完成或手动停止)。 * **非 `0`**:异常退出(结合日志定位具体错误)。 --- ### **3. 启动容器** ```bash docker start xxx # 启动已停止的容器 ``` * **启动后立即退出?** → 继续执行步骤 4。 --- ### **4. 解决启动后立即退出的问题** #### **a. 保持容器前台运行** * **问题本质**:容器内**主进程结束**会导致容器退出。 * **解决方案**: * **修改启动命令**:确保主进程持续运行(如 MySQL 用 `mysqld`,而非 `mysql`)。 * **添加前台参数**:例如 Redis 用 `redis-server --daemonize no`。 * **使用 `tail -f` 保活**(临时方案): ```bash docker run -d --name=xxx image_name tail -f /dev/null ``` #### **b. 检查资源限制** ```bash docker stats xxx # 查看容器的 CPU/内存使用 ``` * **内存不足(OOM)**:增加内存限制(`-m 512m`)或优化应用。 #### **c. 检查文件系统权限** * 容器内进程可能因**无写权限**崩溃(如日志目录 `/var/log`)。 * **解决方案**:启动时映射可写目录(`-v /host/log:/container/log`)或修改容器内权限。 --- ### **5. 进入已停止的容器(调试用)** 若需调试停止的容器,可**提交为临时镜像**进入: ```bash docker commit xxx temp-image # 基于停止的容器创建临时镜像 docker run -it --rm temp-image /bin/bash # 进入临时镜像的 Shell ``` --- ### **6. 设置自动重启策略** 为避免容器意外退出后需手动启动,添加重启策略: ```bash docker run -d --restart=always --name=xxx image_name # 容器退出时自动重启 ``` --- ### **关键总结** | **现象** | **原因** | **解决方案** | |------------------------|-------------------------|----------------------------------| | 容器状态为 `Exited` | 正常停止/任务完成 | `docker start xxx` | | 容器状态为 `Exited` | 端口冲突/配置错误 | 查日志 → 修改配置 → 重启 | | 容器状态为 `Created` | 从未启动 | `docker start xxx` | | 启动后立即退出 | 主进程结束/资源不足 | 保持前台进程/增加资源/检查权限 | | 需操作未运行的容器 | Docker 设计限制 | 先启动容器或提交为临时镜像进入 | > **示例修复流程**: > 1. `docker ps -a` → 发现容器状态为 `Exited` > 2. `docker logs xxx` → 发现报错 `Port 6379 is not available` > 3. `sudo lsof -i :6379` → 找到占用进程并停止 > 4. `docker start xxx` → 成功启动容器 > 5. `docker exec -it xxx redis-cli` → 正常进入容器 [^2][^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值